vdl: Add codegen for Any, and fix some VDLRead bugs.

After this CL, if you manually replace vom.Decoder with
vom.XDecoder, all tests pass, except for a single failure
involving a nil vom.RawBytes.

MultiPart: 1/2
Change-Id: I6d96d7e6f655e859dde9dc2189f621fe6f125866
diff --git a/security/security.vdl.go b/security/security.vdl.go
index 956284a..7c3deb2 100644
--- a/security/security.vdl.go
+++ b/security/security.vdl.go
@@ -1729,7 +1729,9 @@
 			return dec.FinishValue()
 		}
 		var elem *vom.RawBytes
-		// TODO(toddw): implement any
+		if err = elem.VDLRead(dec); err != nil {
+			return err
+		}
 		*x = append(*x, elem)
 	}
 }
diff --git a/services/syncbase/syncbase.vdl.go b/services/syncbase/syncbase.vdl.go
index 52eb615..5285937 100644
--- a/services/syncbase/syncbase.vdl.go
+++ b/services/syncbase/syncbase.vdl.go
@@ -5098,7 +5098,9 @@
 		case "":
 			return dec.FinishValue()
 		case "Value":
-			// TODO(toddw): implement any
+			if err = x.Value.VDLRead(dec); err != nil {
+				return err
+			}
 		case "FromSync":
 			if err = dec.StartValue(); err != nil {
 				return err
diff --git a/services/watch/watch.vdl.go b/services/watch/watch.vdl.go
index a53a3cf..901d0d3 100644
--- a/services/watch/watch.vdl.go
+++ b/services/watch/watch.vdl.go
@@ -624,7 +624,9 @@
 				return err
 			}
 		case "Value":
-			// TODO(toddw): implement any
+			if err = x.Value.VDLRead(dec); err != nil {
+				return err
+			}
 		case "ResumeMarker":
 			if err = x.ResumeMarker.VDLRead(dec); err != nil {
 				return err
diff --git a/vdl/.api b/vdl/.api
index 4b4d25f..c45abe2 100644
--- a/vdl/.api
+++ b/vdl/.api
@@ -34,6 +34,7 @@
 pkg vdl, func Compatible(*Type, *Type) bool
 pkg vdl, func Convert(interface{}, interface{}) error
 pkg vdl, func CopyValue(*Value) *Value
+pkg vdl, func DeepEqual(interface{}, interface{}) bool
 pkg vdl, func EnumType(...string) *Type
 pkg vdl, func EqualValue(*Value, *Value) bool
 pkg vdl, func Float32Value(float32) *Value
@@ -446,6 +447,7 @@
 pkg vdl, method (*Value) TypeObject() *Type
 pkg vdl, method (*Value) Uint() uint64
 pkg vdl, method (*Value) UnionField() (int, *Value)
+pkg vdl, method (*Value) VDLEqual(interface{}) bool
 pkg vdl, method (*Value) VDLRead(Decoder) error
 pkg vdl, method (*WireError) FillVDLTarget(Target, *Type) error
 pkg vdl, method (*WireError) MakeVDLTarget() Target
@@ -540,6 +542,8 @@
 pkg vdl, type Encoder interface, FinishValue() error
 pkg vdl, type Encoder interface, StartComposite() error
 pkg vdl, type Encoder interface, StartValue(*Type) error
+pkg vdl, type Equaler interface { VDLEqual }
+pkg vdl, type Equaler interface, VDLEqual(interface{}) bool
 pkg vdl, type Field struct
 pkg vdl, type Field struct, Name string
 pkg vdl, type Field struct, Type *Type
diff --git a/vdl/coder.go b/vdl/coder.go
index 347b324..b6749e5 100644
--- a/vdl/coder.go
+++ b/vdl/coder.go
@@ -8,9 +8,9 @@
 
 // Reader is the interface that wraps the VDLRead method.
 //
-// VDLRead fills in the the underlying value (that implements this method) from
-// the Decoder.  This method is auto-generated for all types defined in vdl.  It
-// may be implemented for regular Go types not defined in vdl, to customize the
+// VDLRead fills in the the receiver that implements this method from the
+// Decoder.  This method is auto-generated for all types defined in vdl.  It may
+// be implemented for regular Go types not defined in vdl, to customize the
 // decoding.
 type Reader interface {
 	VDLRead(dec Decoder) error
@@ -18,9 +18,9 @@
 
 // Writer is the interface that wraps the VDLWrite method.
 //
-// VDLWrite writes out the underlying value (that implements this method) to the
-// Encoder.  This method is auto-generated for all types defined in vdl.  It may
-// be implemented for regular Go types not defined in vdl, to customize the
+// VDLWrite writes out the receiver that implements this method to the Encoder.
+// This method is auto-generated for all types defined in vdl.  It may be
+// implemented for regular Go types not defined in vdl, to customize the
 // encoding.
 type Writer interface {
 	VDLWrite(enc Encoder) error
@@ -125,7 +125,7 @@
 
 func decoderCompatible(dec Decoder, tt *Type) error {
 	if (dec.StackDepth() == 1 || dec.IsAny()) && !Compatible(tt, dec.Type()) {
-		return fmt.Errorf("incompatible %v %v, from %v", tt.Kind(), tt, dec.Type())
+		return fmt.Errorf("incompatible %v, from %v", tt, dec.Type())
 	}
 	return nil
 }
diff --git a/vdl/deep_equal.go b/vdl/deep_equal.go
new file mode 100644
index 0000000..ad748e0
--- /dev/null
+++ b/vdl/deep_equal.go
@@ -0,0 +1,188 @@
+// Copyright 2016 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vdl
+
+import (
+	"fmt"
+	"reflect"
+	"unsafe"
+)
+
+// TODO(toddw): Add tests.
+
+// Equaler is the interface that wraps the VDLEqual method.
+//
+// VDLEqual returns true iff the receiver that implements this method is equal
+// to v.  The semantics of the equality must abide by VDL equality rules.  The
+// caller of this method must ensure that the type of the receiver is the same
+// as the type of v, and v is never nil.
+type Equaler interface {
+	VDLEqual(v interface{}) bool
+}
+
+// DeepEqual is like reflect.DeepEqual, with the following differences:
+//   1. If a value is encountered that implements Equaler, we will use that for
+//      the comparison.
+//   2. If cyclic values are encountered, we require that the cyclic structure
+//      of the two values is the same.
+func DeepEqual(a, b interface{}) bool {
+	return deepEqual(reflect.ValueOf(a), reflect.ValueOf(b), nil, nil)
+}
+
+func findPathIndex(path []unsafe.Pointer, target unsafe.Pointer) int {
+	for index, item := range path {
+		if item == target {
+			return index
+		}
+	}
+	return -1
+}
+
+func deepEqual(a, b reflect.Value, pathA, pathB []unsafe.Pointer) bool {
+	if !a.IsValid() || !b.IsValid() {
+		return a.IsValid() == b.IsValid()
+	}
+	if a.Type() != b.Type() {
+		return false
+	}
+
+	// Handle VDLEqual comparisons.
+	if a.Kind() != reflect.Ptr || (!a.IsNil() && !b.IsNil()) {
+		// It would be nice to use a.Interface() to get the actual value, and then
+		// call the VDLEqual method directly.  But a.Interface() panics if a is an
+		// unexported struct field.  We might actually encounter this case, if we
+		// change our codegen to include an unexported "unknown bytes" field in
+		// structs, in order to avoid read-modify-write slicing.
+		//
+		// TODO(toddw): Verify the logic below actually allows us to find and call
+		// the VDLEqual method, if a is an unexported struct field.
+		if rvEqual := a.MethodByName("VDLEqual"); rvEqual.IsValid() {
+			return rvEqual.Call([]reflect.Value{b})[0].Bool()
+		}
+	}
+
+	// In order to handle cyclic values, we keep the path of possible "pointees"
+	// as we traverse the value, where the "pointee" is the address that a pointer
+	// could point to.  The pointer handling case below uses this information to
+	// detect and handle cycles.
+	//
+	// We must convert the result of reflect.Value.UnsafeAddr() to unsafe.Pointer
+	// in the same expression.  See https://golang.org/pkg/unsafe/#Pointer
+	switch canA, canB := a.CanAddr(), b.CanAddr(); {
+	case canA && canB:
+		pathA = append(pathA, unsafe.Pointer(a.UnsafeAddr()))
+		pathB = append(pathB, unsafe.Pointer(b.UnsafeAddr()))
+	case canA:
+		pathA = append(pathA, unsafe.Pointer(a.UnsafeAddr()))
+		pathB = append(pathB, unsafe.Pointer(uintptr(0)))
+	case canB:
+		pathA = append(pathA, unsafe.Pointer(uintptr(0)))
+		pathB = append(pathB, unsafe.Pointer(b.UnsafeAddr()))
+	}
+
+	switch a.Kind() {
+	case reflect.Ptr:
+		if a.IsNil() || b.IsNil() {
+			return a.IsNil() == b.IsNil()
+		}
+		// We must convert the result of reflect.Value.Pointer() to unsafe.Pointer
+		// in the same expression.  See https://golang.org/pkg/unsafe/#Pointer
+		pa, pb := unsafe.Pointer(a.Pointer()), unsafe.Pointer(b.Pointer())
+		if pa == pb {
+			// If the pointers are equal, the values are equal.
+			return true
+		}
+		switch indexA, indexB := findPathIndex(pathA, pa), findPathIndex(pathB, pb); {
+		case indexA != indexB:
+			// The index is -1 if the pointer doesn't exist in the path, meaning this
+			// isn't a cyclic value.  Otherwise the index tells us the which item the
+			// cycle points back to.  Either way, if they are different, the values
+			// are not equal.
+			return false
+		case indexA != -1:
+			// If both values have cycles pointing back to the same relative item, we
+			// need to stop, otherwise there is an infinite loop.  All previous items
+			// in the path were equal, so we return true.
+			return true
+		}
+		return deepEqual(a.Elem(), b.Elem(), pathA, pathB)
+	case reflect.Array:
+		if a.Len() != b.Len() {
+			return false
+		}
+		for ix := 0; ix < a.Len(); ix++ {
+			if !deepEqual(a.Index(ix), b.Index(ix), pathA, pathB) {
+				return false
+			}
+		}
+		return true
+	case reflect.Slice:
+		if a.IsNil() || b.IsNil() {
+			return a.IsNil() == b.IsNil()
+		}
+		if a.Len() != b.Len() {
+			return false
+		}
+		for ix := 0; ix < a.Len(); ix++ {
+			if !deepEqual(a.Index(ix), b.Index(ix), pathA, pathB) {
+				return false
+			}
+		}
+		return true
+	case reflect.Map:
+		if a.IsNil() || b.IsNil() {
+			return a.IsNil() == b.IsNil()
+		}
+		if a.Len() != b.Len() {
+			return false
+		}
+		for _, key := range a.MapKeys() {
+			if !deepEqual(a.MapIndex(key), b.MapIndex(key), pathA, pathB) {
+				return false
+			}
+		}
+		return true
+	case reflect.Struct:
+		for ix := 0; ix < a.NumField(); ix++ {
+			if !deepEqual(a.Field(ix), b.Field(ix), pathA, pathB) {
+				return false
+			}
+		}
+		return true
+	case reflect.Interface:
+		if a.IsNil() || b.IsNil() {
+			return a.IsNil() == b.IsNil()
+		}
+		return deepEqual(a.Elem(), b.Elem(), pathA, pathB)
+
+		// Ideally we would add a default clause here that would just return
+		// a.Interface() == b.Interface(), but that panics if we're dealing with
+		// unexported fields.  Instead we check each case manually.
+
+	case reflect.Bool:
+		return a.Bool() == b.Bool()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return a.Int() == b.Int()
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return a.Uint() == b.Uint()
+	case reflect.Float32, reflect.Float64:
+		return a.Float() == b.Float()
+	case reflect.Complex64, reflect.Complex128:
+		return a.Complex() == b.Complex()
+	case reflect.String:
+		return a.String() == b.String()
+	case reflect.UnsafePointer:
+		return a.Pointer() == b.Pointer()
+	case reflect.Func:
+		// Same as regular Go comparisons; non-nil functions can't be compared.
+		return a.IsNil() && b.IsNil()
+	case reflect.Chan:
+		// We must convert the result of reflect.Value.Pointer() to unsafe.Pointer
+		// in the same expression.  See https://golang.org/pkg/unsafe/#Pointer
+		return unsafe.Pointer(a.Pointer()) == unsafe.Pointer(b.Pointer())
+	default:
+		panic(fmt.Errorf("DeepEqual unhandled kind %v type %q", a.Kind(), a.Type()))
+	}
+}
diff --git a/vdl/reflect_reader.go b/vdl/reflect_reader.go
index 8260e6b..749bad5 100644
--- a/vdl/reflect_reader.go
+++ b/vdl/reflect_reader.go
@@ -183,7 +183,7 @@
 	// Walk pointers and check for faster non-reflect support, which handles
 	// vdl.Value and vom.RawBytes, and any other special-cases.
 	rv = readWalkPointers(rv)
-	if err := readNonReflect(dec, true, rv.Addr().Interface()); err != errReadMustReflect {
+	if err := readNonReflect(dec, false, rv.Addr().Interface()); err != errReadMustReflect {
 		return err
 	}
 	// The only case left is to handle interfaces.  We allow decoding into
@@ -206,10 +206,16 @@
 	// TODO(toddw): Replace typeToReflectFixed with TypeToReflect, after we've
 	// fixed it to treat the error type correctly.
 	rtDecode := typeToReflectFixed(dec.Type())
-	switch {
-	case rtDecode == nil:
+	if rtDecode == nil {
 		return fmt.Errorf("vdl: %v not registered, call vdl.Register, or use vdl.Value or vom.RawBytes instead", dec.Type())
-	case !rtDecode.Implements(rv.Type()):
+	}
+	// If we decoded an optional type, ensure that it is a pointer.  Note that if
+	// we decoded a nil, dec.Type() is already optional, so rtDecode will already
+	// be a pointer.
+	if dec.IsOptional() && !dec.IsNil() {
+		rtDecode = reflect.PtrTo(rtDecode)
+	}
+	if !rtDecode.Implements(rv.Type()) {
 		return fmt.Errorf("vdl: %v doesn't implement %v", rtDecode, rv.Type())
 	}
 	// Handle decoding optional(nil), by setting rv to a nil pointer of the
@@ -377,7 +383,7 @@
 		if err := readReflect(dec, false, elem, tt.Elem()); err != nil {
 			return err
 		}
-		rv = reflect.Append(rv, elem)
+		rv.Set(reflect.Append(rv, elem))
 	}
 }
 
@@ -433,11 +439,8 @@
 
 func readStruct(dec Decoder, rv reflect.Value, tt *Type) error {
 	rt := rv.Type()
-	// Reset to zero struct, since fields may be missing.
-	//
-	// TODO(toddw): We need something like rvSettableZeroValue here, unless we can
-	// ensure go zero values represent VDL zero values as well.
-	rv.Set(reflect.Zero(rt))
+	// Reset to the zero struct, since fields may be missing.
+	rv.Set(rvSettableZeroValue(rt, tt))
 	for {
 		name, err := dec.NextField()
 		switch {
diff --git a/vdl/value.go b/vdl/value.go
index 49415d5..0434f60 100644
--- a/vdl/value.go
+++ b/vdl/value.go
@@ -331,6 +331,11 @@
 // Type returns the type of v.  All valid values have a non-nil type.
 func (v *Value) Type() *Type { return v.t }
 
+// VDLEqual implements the Equaler interface method.
+func (v *Value) VDLEqual(x interface{}) bool {
+	return EqualValue(v, x.(*Value))
+}
+
 // Bool returns the underlying value of a Bool.
 func (v *Value) Bool() bool {
 	v.t.checkKind("Bool", Bool)
diff --git a/vdl/value_reader.go b/vdl/value_reader.go
index e6a98f6..251927b 100644
--- a/vdl/value_reader.go
+++ b/vdl/value_reader.go
@@ -8,7 +8,7 @@
 	"fmt"
 )
 
-// VDLRead uses dec to decode a value in vv.  If vv isn't valid (i.e. has no
+// VDLRead uses dec to decode a value into vv.  If vv isn't valid (i.e. has no
 // type), it will be filled in the exact type of value read from the decoder.
 // Otherwise the type of vv must be compatible with the type of the value read
 // from the decoder.
@@ -21,16 +21,23 @@
 	}
 	if !vv.IsValid() {
 		// Initialize vv to the zero value of the exact type read from the decoder.
-		// It is as if vv were initialized to that type to begin with.
+		// It is as if vv were initialized with that type to begin with.  The
+		// top-level any type is dropped.
 		switch {
-		case dec.IsAny():
-			*vv = *ZeroValue(AnyType)
-		case dec.IsOptional():
+		case dec.IsOptional() && !dec.IsNil():
 			*vv = *ZeroValue(OptionalType(dec.Type()))
 		default:
 			*vv = *ZeroValue(dec.Type())
 		}
 	}
+	dec.IgnoreNextStartValue()
+	return vv.read(dec)
+}
+
+func (vv *Value) read(dec Decoder) error {
+	if err := dec.StartValue(); err != nil {
+		return err
+	}
 	if err := decoderCompatible(dec, vv.Type()); err != nil {
 		return err
 	}
@@ -177,7 +184,7 @@
 		case done:
 			return nil
 		}
-		if err := vv.Index(index).VDLRead(dec); err != nil {
+		if err := vv.Index(index).read(dec); err != nil {
 			return err
 		}
 		index++
@@ -218,7 +225,7 @@
 			vv.AssignLen(cap)
 			vv.AssignLen(needLen)
 		}
-		if err := vv.Index(index).VDLRead(dec); err != nil {
+		if err := vv.Index(index).read(dec); err != nil {
 			return err
 		}
 		index++
@@ -237,7 +244,7 @@
 			return nil
 		}
 		key := ZeroValue(vv.Type().Key())
-		if err := key.VDLRead(dec); err != nil {
+		if err := key.read(dec); err != nil {
 			return err
 		}
 		vv.AssignSetKey(key)
@@ -256,11 +263,11 @@
 			return nil
 		}
 		key := ZeroValue(vv.Type().Key())
-		if err := key.VDLRead(dec); err != nil {
+		if err := key.read(dec); err != nil {
 			return err
 		}
 		elem := ZeroValue(vv.Type().Elem())
-		if err := elem.VDLRead(dec); err != nil {
+		if err := elem.read(dec); err != nil {
 			return err
 		}
 		vv.AssignMapIndex(key, elem)
@@ -283,7 +290,7 @@
 		}
 		switch field := vv.StructFieldByName(name); {
 		case field != nil:
-			if err := field.VDLRead(dec); err != nil {
+			if err := field.read(dec); err != nil {
 				return err
 			}
 		default:
@@ -310,7 +317,7 @@
 		return fmt.Errorf("field %q not in union %v, from %v", name, vv.Type(), dec.Type())
 	}
 	elem := ZeroValue(field.Type)
-	if err := elem.VDLRead(dec); err != nil {
+	if err := elem.read(dec); err != nil {
 		return err
 	}
 	vv.AssignUnionField(index, elem)
diff --git a/vdl/vdl.vdl.go b/vdl/vdl.vdl.go
index c4b7a58..c6f118e 100644
--- a/vdl/vdl.vdl.go
+++ b/vdl/vdl.vdl.go
@@ -432,7 +432,10 @@
 			return dec.FinishValue()
 		}
 		var elem *Value
-		// TODO(toddw): implement any
+		elem = new(Value)
+		if err = elem.VDLRead(dec); err != nil {
+			return err
+		}
 		*x = append(*x, elem)
 	}
 }
diff --git a/vdlroot/signature/signature.vdl.go b/vdlroot/signature/signature.vdl.go
index 76892ba..d74f682 100644
--- a/vdlroot/signature/signature.vdl.go
+++ b/vdlroot/signature/signature.vdl.go
@@ -977,7 +977,10 @@
 			return dec.FinishValue()
 		}
 		var elem *vdl.Value
-		// TODO(toddw): implement any
+		elem = new(vdl.Value)
+		if err = elem.VDLRead(dec); err != nil {
+			return err
+		}
 		*x = append(*x, elem)
 	}
 }
diff --git a/vom/.api b/vom/.api
index f67ad3d..6350bb2 100644
--- a/vom/.api
+++ b/vom/.api
@@ -101,6 +101,7 @@
 pkg vom, method (*TypeDecoder) Stop()
 pkg vom, method (*XDecoder) Decode(interface{}) error
 pkg vom, method (*XDecoder) Decoder() vdl.Decoder
+pkg vom, method (*XDecoder) Ignore() error
 pkg vom, method (ControlKind) String() string
 pkg vom, method (DumpAtom) String() string
 pkg vom, method (DumpKind) String() string
diff --git a/vom/decoder_test.go b/vom/decoder_test.go
index 2f4c237..b488c54 100644
--- a/vom/decoder_test.go
+++ b/vom/decoder_test.go
@@ -81,7 +81,7 @@
 			return
 		}
 		if want := value; !vdl.EqualValue(got, want) {
-			t.Errorf("%s: Decode mismatch\nGOT %v\nWANT %v", head, got, want)
+			t.Errorf("%s: Decode mismatch\nGOT  %v\nWANT %v", head, got, want)
 			return
 		}
 	}
@@ -99,7 +99,7 @@
 		return
 	}
 	if want := value; !vdl.EqualValue(got, want) {
-		t.Errorf("%s: Decode mismatch\nGOT %v\nWANT %v", head, got, want)
+		t.Errorf("%s: Decode mismatch\nGOT  %v\nWANT %v", head, got, want)
 		return
 	}
 }
@@ -119,7 +119,7 @@
 			return
 		}
 		if want := value; !vdl.EqualValue(got, want) {
-			t.Errorf("%s: Decode mismatch\nGOT %v\nWANT %v", head, got, want)
+			t.Errorf("%s: Decode mismatch\nGOT  %v\nWANT %v", head, got, want)
 			return
 		}
 		typedec.Stop()
@@ -138,8 +138,8 @@
 			t.Errorf("%s: Decode failed: %v", head, err)
 			return
 		}
-		if !reflect.DeepEqual(got, want) {
-			t.Errorf("%s: Decode mismatch\nGOT %T %#v\nWANT %T %#v", head, got, got, want, want)
+		if !vdl.DeepEqual(got, want) {
+			t.Errorf("%s: Decode mismatch\nGOT  %T %+v\nWANT %T %+v", head, got, got, want, want)
 			return
 		}
 	}
@@ -158,8 +158,8 @@
 		t.Errorf("%s: Decode failed: %v", head, err)
 		return
 	}
-	if !reflect.DeepEqual(got, want) {
-		t.Errorf("%s: Decode mismatch\nGOT %T %#v\nWANT %T %#v", head, got, got, want, want)
+	if !vdl.DeepEqual(got, want) {
+		t.Errorf("%s: Decode mismatch\nGOT  %T %+v\nWANT %T %+v", head, got, got, want, want)
 		return
 	}
 }
@@ -178,8 +178,8 @@
 			t.Errorf("%s: Decode failed: %v", head, err)
 			return
 		}
-		if !reflect.DeepEqual(got, want) {
-			t.Errorf("%s: Decode mismatch\nGOT %T %#v\nWANT %T %#v", head, got, got, want, want)
+		if !vdl.DeepEqual(got, want) {
+			t.Errorf("%s: Decode mismatch\nGOT  %T %+v\nWANT %T %+v", head, got, got, want, want)
 			return
 		}
 		typedec.Stop()
@@ -272,7 +272,7 @@
 			defer wg.Done()
 			for _, n := range rand.Perm(len(tests) * 10) {
 				test := tests[n%len(tests)]
-				name := fmt.Sprintf("[%d]:%#v,%#v", n, test.In, test.Want)
+				name := fmt.Sprintf("[%d]:%+v,%+v", n, test.In, test.Want)
 
 				var (
 					encoder *Encoder
@@ -288,7 +288,7 @@
 				}
 
 				if err := encoder.Encode(test.In); err != nil {
-					t.Errorf("%s: Encode(%#v) failed: %v", name, test.In, err)
+					t.Errorf("%s: Encode(%+v) failed: %v", name, test.In, err)
 					return
 				}
 				rv := reflect.New(reflect.TypeOf(test.Want))
@@ -296,8 +296,8 @@
 					t.Errorf("%s: Decode failed: %v", name, err)
 					return
 				}
-				if got := rv.Elem().Interface(); !reflect.DeepEqual(got, test.Want) {
-					t.Errorf("%s: Decode mismatch\nGOT %T %#v\nWANT %T %#v", name, got, got, test.Want, test.Want)
+				if got := rv.Elem().Interface(); !vdl.DeepEqual(got, test.Want) {
+					t.Errorf("%s: Decode mismatch\nGOT  %T %+v\nWANT %T %+v", name, got, got, test.Want, test.Want)
 					return
 				}
 			}
@@ -377,9 +377,9 @@
 
 // Test that no EOF is returned from Decode() if the type stream finished before the value stream.
 func TestTypeStreamEndsFirst(t *testing.T) {
-	hexversion := "80"
-	hextype := "5137060029762e696f2f7632332f766f6d2f74657374646174612f7465737474797065732e537472756374416e7901010003416e79010fe1e1533502002d762e696f2f7632332f766f6d2f74657374646174612f7465737474797065732e4e41727261793255696e74363401060202e1"
-	hexvalue := "5206002a000001e1"
+	hexversion := "81"
+	hextype := "5133060025762e696f2f7632332f766f6d2f74657374646174612f74797065732e537472756374416e7901010003416e79010fe1e1533b060023762e696f2f7632332f766f6d2f74657374646174612f74797065732e4e53747275637401030001410101e10001420103e10001430109e1e1"
+	hexvalue := "52012a0103070000000001e1e1"
 	binversion := string(hex2Bin(t, hexversion))
 	bintype := string(hex2Bin(t, hextype))
 	binvalue := string(hex2Bin(t, hexvalue))
diff --git a/vom/testdata/types/types.vdl.go b/vom/testdata/types/types.vdl.go
index 1840320..00c48f8 100644
--- a/vom/testdata/types/types.vdl.go
+++ b/vom/testdata/types/types.vdl.go
@@ -302,7 +302,10 @@
 				return err
 			}
 		case "Value":
-			// TODO(toddw): implement any
+			x.Value = new(vdl.Value)
+			if err = x.Value.VDLRead(dec); err != nil {
+				return err
+			}
 		case "TypeString":
 			if err = dec.StartValue(); err != nil {
 				return err
@@ -632,7 +635,10 @@
 			return dec.FinishValue()
 		}
 		var elem *vdl.Value
-		// TODO(toddw): implement any
+		elem = new(vdl.Value)
+		if err = elem.VDLRead(dec); err != nil {
+			return err
+		}
 		*x = append(*x, elem)
 	}
 }
@@ -3548,7 +3554,10 @@
 				return err
 			}
 		case "F":
-			// TODO(toddw): implement any
+			x.F = new(vdl.Value)
+			if err = x.F.VDLRead(dec); err != nil {
+				return err
+			}
 		default:
 			if err = dec.SkipValue(); err != nil {
 				return err
@@ -6369,7 +6378,10 @@
 				return err
 			}
 		case "D":
-			// TODO(toddw): implement any
+			x.D = new(vdl.Value)
+			if err = x.D.VDLRead(dec); err != nil {
+				return err
+			}
 		case "E":
 			if err = dec.StartValue(); err != nil {
 				return err
@@ -7824,7 +7836,10 @@
 		}
 		var elem *vdl.Value
 		{
-			// TODO(toddw): implement any
+			elem = new(vdl.Value)
+			if err = elem.VDLRead(dec); err != nil {
+				return err
+			}
 		}
 		if tmpMap == nil {
 			tmpMap = make(SometimesSetMap)
@@ -9104,7 +9119,10 @@
 		*x = field
 	case "D":
 		var field BdeUnionD
-		// TODO(toddw): implement any
+		field.Value = new(vdl.Value)
+		if err = field.Value.VDLRead(dec); err != nil {
+			return err
+		}
 		*x = field
 	case "E":
 		var field BdeUnionE
@@ -9529,7 +9547,10 @@
 		case "":
 			return dec.FinishValue()
 		case "Any":
-			// TODO(toddw): implement any
+			x.Any = new(vdl.Value)
+			if err = x.Any.VDLRead(dec); err != nil {
+				return err
+			}
 		default:
 			if err = dec.SkipValue(); err != nil {
 				return err
@@ -10776,7 +10797,10 @@
 			return dec.FinishValue()
 		}
 		var elem *vdl.Value
-		// TODO(toddw): implement any
+		elem = new(vdl.Value)
+		if err = elem.VDLRead(dec); err != nil {
+			return err
+		}
 		*x = append(*x, elem)
 	}
 }
@@ -11140,7 +11164,10 @@
 		case "":
 			return dec.FinishValue()
 		case "Payload":
-			// TODO(toddw): implement any
+			x.Payload = new(vdl.Value)
+			if err = x.Payload.VDLRead(dec); err != nil {
+				return err
+			}
 		case "Next":
 			if err = dec.StartValue(); err != nil {
 				return err
diff --git a/vom/type_decoder.go b/vom/type_decoder.go
index 654f328..9a93979 100644
--- a/vom/type_decoder.go
+++ b/vom/type_decoder.go
@@ -35,7 +35,7 @@
 	buildCond *sync.Cond
 	err       error               // GUARDED_BY(buildMu)
 	idToWire  map[typeId]wireType // GUARDED_BY(buildMu)
-	dec       *Decoder            // GUARDED_BY(buildMu)
+	dec       *xDecoder           // GUARDED_BY(buildMu)
 
 	processingControlMu sync.Mutex
 	goroutineRunning    bool // GUARDED_BY(processingControlMu)
@@ -52,10 +52,7 @@
 	td := &TypeDecoder{
 		idToType: make(map[typeId]*vdl.Type),
 		idToWire: make(map[typeId]wireType),
-		dec: &Decoder{
-			buf:     buf,
-			typeDec: nil,
-		},
+		dec:      &xDecoder{old: &Decoder{buf: buf}},
 	}
 	td.buildCond = sync.NewCond(&td.buildMu)
 	return td
@@ -65,10 +62,7 @@
 	td := &TypeDecoder{
 		idToType: orig.idToType,
 		idToWire: orig.idToWire,
-		dec: &Decoder{
-			buf:     buf,
-			typeDec: nil,
-		},
+		dec:      &xDecoder{old: &Decoder{buf: buf}},
 	}
 	td.buildCond = sync.NewCond(&td.buildMu)
 	return td
@@ -130,8 +124,8 @@
 		return err
 	}
 
-	if !d.dec.typeIncomplete {
-		if err := d.buildType(curTypeID); d.dec.buf.version >= Version81 && err != nil {
+	if !d.dec.old.typeIncomplete {
+		if err := d.buildType(curTypeID); d.dec.old.buf.version >= Version81 && err != nil {
 			return err
 		}
 	}
diff --git a/vom/xdecoder.go b/vom/xdecoder.go
index b302e45..c30b501 100644
--- a/vom/xdecoder.go
+++ b/vom/xdecoder.go
@@ -71,6 +71,10 @@
 	return vdl.Read(d.dec, v)
 }
 
+func (d *XDecoder) Ignore() error {
+	return d.dec.old.Ignore()
+}
+
 func (d *xDecoder) IgnoreNextStartValue() {
 	d.ignoreNextStartValue = true
 }
@@ -79,9 +83,34 @@
 	return len(d.stack)
 }
 
-// readRawBytes fills in rb with the next value.  It can be called for both
+func (d *xDecoder) decodeWireType(wt *wireType) (typeId, error) {
+	// TODO(toddw): Flip useOldDecoder=false to enable XDecoder.
+	const useOldDecoder = true
+	if useOldDecoder {
+		return d.old.decodeWireType(wt)
+	}
+	// Type messages are just a regularly encoded wireType, which is a union.  To
+	// decode we pre-populate the stack with an entry for the wire type, and run
+	// the code-generated vdlReadWireType method.
+	tid, err := d.old.nextMessage()
+	if err != nil {
+		return 0, err
+	}
+	d.stack = append(d.stack, decoderStackEntry{
+		Type:    wireTypeType,
+		Index:   -1,
+		LenHint: 1, // wireType is a union
+	})
+	d.ignoreNextStartValue = true
+	if err := vdlReadWireType(d, wt); err != nil {
+		return 0, err
+	}
+	return tid, nil
+}
+
+// readRawBytes fills in raw with the next value.  It can be called for both
 // top-level and internal values.
-func (d *xDecoder) readRawBytes(rb *RawBytes) error {
+func (d *xDecoder) readRawBytes(raw *RawBytes) error {
 	if d.ignoreNextStartValue {
 		// If the user has already called StartValue on the decoder, it's harder to
 		// capture all the raw bytes, since the optional flag and length hints have
@@ -99,7 +128,7 @@
 		if err != nil {
 			return err
 		}
-		if err := d.old.decodeRaw(tt, anyLen, rb); err != nil {
+		if err := d.old.decodeRaw(tt, anyLen, raw); err != nil {
 			return err
 		}
 		return d.old.endMessage()
@@ -119,14 +148,14 @@
 	if ttElem == nil {
 		// This is a nil any value, which has already been read by readAnyHeader.
 		// We simply fill in RawBytes with the single WireCtrlNil byte.
-		rb.Version = d.old.buf.version
-		rb.Type = vdl.AnyType
-		rb.RefTypes = nil
-		rb.AnyLengths = nil
-		rb.Data = []byte{WireCtrlNil}
+		raw.Version = d.old.buf.version
+		raw.Type = vdl.AnyType
+		raw.RefTypes = nil
+		raw.AnyLengths = nil
+		raw.Data = []byte{WireCtrlNil}
 		return nil
 	}
-	return d.old.decodeRaw(ttElem, anyLen, rb)
+	return d.old.decodeRaw(ttElem, anyLen, raw)
 }
 
 func (d *xDecoder) StartValue() error {