diff --git a/go/src/v.io/x/mojo/proxy/clientproxy/clientproxy.go b/go/src/v.io/x/mojo/proxy/clientproxy/clientproxy.go
index 9aa5f64..fb16bc8 100644
--- a/go/src/v.io/x/mojo/proxy/clientproxy/clientproxy.go
+++ b/go/src/v.io/x/mojo/proxy/clientproxy/clientproxy.go
@@ -21,7 +21,7 @@
 	"v.io/v23/vom"
 	"v.io/x/mojo/proxy/util"
 	"v.io/x/mojo/transcoder"
-	_ "v.io/x/ref/runtime/factories/roaming"
+	"v.io/x/ref/runtime/factories/roaming"
 )
 
 //#include "mojo/public/c/system/types.h"
@@ -207,7 +207,8 @@
 }
 
 func (delegate *delegate) Initialize(context application.Context) {
-	ctx, shutdown := v23.Init(context)
+	roaming.SetArgs(context)
+	ctx, shutdown := v23.Init()
 	delegate.ctx = ctx
 	delegate.shutdown = shutdown
 	ctx.Infof("delegate.Initialize...")
diff --git a/go/src/v.io/x/mojo/proxy/serverproxy/serverproxy.go b/go/src/v.io/x/mojo/proxy/serverproxy/serverproxy.go
index 3cd024d..e4e5658 100644
--- a/go/src/v.io/x/mojo/proxy/serverproxy/serverproxy.go
+++ b/go/src/v.io/x/mojo/proxy/serverproxy/serverproxy.go
@@ -23,10 +23,10 @@
 	"v.io/v23/security"
 	"v.io/v23/vdl"
 	"v.io/v23/vdlroot/signature"
+	"v.io/v23/vom"
 	"v.io/x/mojo/proxy/util"
 	"v.io/x/mojo/transcoder"
-	_ "v.io/x/ref/runtime/factories/roaming"
-	"v.io/v23/vom"
+	"v.io/x/ref/runtime/factories/roaming"
 )
 
 //#include "mojo/public/c/system/types.h"
@@ -262,7 +262,6 @@
 	return target.Fields(), nil
 }
 
-
 func encodeMessageFromVom(header bindings.MessageHeader, argptrs []interface{}, t *vdl.Type) (*bindings.Message, error) {
 	// Convert argptrs into their true form: []*vom.RawBytes
 	inargs := make([]*vom.RawBytes, len(argptrs))
@@ -336,7 +335,8 @@
 	// Start up v23 whenever a v23proxy is begun.
 	// This is done regardless of whether we are initializing this v23proxy for use
 	// as a client or as a server.
-	ctx, shutdown := v23.Init(context)
+	roaming.SetArgs(context)
+	ctx, shutdown := v23.Init()
 	delegate.ctx = ctx
 	delegate.shutdown = shutdown
 	ctx.Infof("delegate.Initialize...")
diff --git a/go/src/v.io/x/mojo/transcoder/internal/internal.vdl.go b/go/src/v.io/x/mojo/transcoder/internal/internal.vdl.go
new file mode 100644
index 0000000..ae3c6a8
--- /dev/null
+++ b/go/src/v.io/x/mojo/transcoder/internal/internal.vdl.go
@@ -0,0 +1,914 @@
+// Copyright 2015 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.
+
+// This file was auto-generated by the vanadium vdl tool.
+// Package: internal
+
+package internal
+
+import (
+	"fmt"
+	"reflect"
+	"v.io/v23/vdl"
+)
+
+var _ = __VDLInit() // Must be first; see __VDLInit comments for details.
+
+//////////////////////////////////////////////////
+// Type definitions
+
+type AddressInfo struct {
+	Street string
+	City   string
+	State  string
+	Zip    string
+}
+
+func (AddressInfo) __VDLReflect(struct {
+	Name string `vdl:"src/v.io/x/mojo/transcoder/internal.AddressInfo"`
+}) {
+}
+
+func (m *AddressInfo) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Street")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget3.FromString(string(m.Street), tt.NonOptional().Field(0).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+			return err
+		}
+	}
+	keyTarget4, fieldTarget5, err := fieldsTarget1.StartField("City")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget5.FromString(string(m.City), tt.NonOptional().Field(1).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget4, fieldTarget5); err != nil {
+			return err
+		}
+	}
+	keyTarget6, fieldTarget7, err := fieldsTarget1.StartField("State")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget7.FromString(string(m.State), tt.NonOptional().Field(2).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget6, fieldTarget7); err != nil {
+			return err
+		}
+	}
+	keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("Zip")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget9.FromString(string(m.Zip), tt.NonOptional().Field(3).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
+			return err
+		}
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *AddressInfo) MakeVDLTarget() vdl.Target {
+	return &AddressInfoTarget{Value: m}
+}
+
+type AddressInfoTarget struct {
+	Value        *AddressInfo
+	streetTarget vdl.StringTarget
+	cityTarget   vdl.StringTarget
+	stateTarget  vdl.StringTarget
+	zipTarget    vdl.StringTarget
+	vdl.TargetBase
+	vdl.FieldsTargetBase
+}
+
+func (t *AddressInfoTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
+
+	if ttWant := vdl.TypeOf((*AddressInfo)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
+		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
+	}
+	return t, nil
+}
+func (t *AddressInfoTarget) StartField(name string) (key, field vdl.Target, _ error) {
+	switch name {
+	case "Street":
+		t.streetTarget.Value = &t.Value.Street
+		target, err := &t.streetTarget, error(nil)
+		return nil, target, err
+	case "City":
+		t.cityTarget.Value = &t.Value.City
+		target, err := &t.cityTarget, error(nil)
+		return nil, target, err
+	case "State":
+		t.stateTarget.Value = &t.Value.State
+		target, err := &t.stateTarget, error(nil)
+		return nil, target, err
+	case "Zip":
+		t.zipTarget.Value = &t.Value.Zip
+		target, err := &t.zipTarget, error(nil)
+		return nil, target, err
+	default:
+		return nil, nil, fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/internal.AddressInfo", name)
+	}
+}
+func (t *AddressInfoTarget) FinishField(_, _ vdl.Target) error {
+	return nil
+}
+func (t *AddressInfoTarget) FinishFields(_ vdl.FieldsTarget) error {
+
+	return nil
+}
+
+type CreditAgency int
+
+const (
+	CreditAgencyEquifax CreditAgency = iota
+	CreditAgencyExperian
+	CreditAgencyTransUnion
+)
+
+// CreditAgencyAll holds all labels for CreditAgency.
+var CreditAgencyAll = [...]CreditAgency{CreditAgencyEquifax, CreditAgencyExperian, CreditAgencyTransUnion}
+
+// CreditAgencyFromString creates a CreditAgency from a string label.
+func CreditAgencyFromString(label string) (x CreditAgency, err error) {
+	err = x.Set(label)
+	return
+}
+
+// Set assigns label to x.
+func (x *CreditAgency) Set(label string) error {
+	switch label {
+	case "Equifax", "equifax":
+		*x = CreditAgencyEquifax
+		return nil
+	case "Experian", "experian":
+		*x = CreditAgencyExperian
+		return nil
+	case "TransUnion", "transunion":
+		*x = CreditAgencyTransUnion
+		return nil
+	}
+	*x = -1
+	return fmt.Errorf("unknown label %q in internal.CreditAgency", label)
+}
+
+// String returns the string label of x.
+func (x CreditAgency) String() string {
+	switch x {
+	case CreditAgencyEquifax:
+		return "Equifax"
+	case CreditAgencyExperian:
+		return "Experian"
+	case CreditAgencyTransUnion:
+		return "TransUnion"
+	}
+	return ""
+}
+
+func (CreditAgency) __VDLReflect(struct {
+	Name string `vdl:"src/v.io/x/mojo/transcoder/internal.CreditAgency"`
+	Enum struct{ Equifax, Experian, TransUnion string }
+}) {
+}
+
+func (m *CreditAgency) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	if err := t.FromEnumLabel((*m).String(), tt); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *CreditAgency) MakeVDLTarget() vdl.Target {
+	return &CreditAgencyTarget{Value: m}
+}
+
+type CreditAgencyTarget struct {
+	Value *CreditAgency
+	vdl.TargetBase
+}
+
+func (t *CreditAgencyTarget) FromEnumLabel(src string, tt *vdl.Type) error {
+
+	if ttWant := vdl.TypeOf((*CreditAgency)(nil)); !vdl.Compatible(tt, ttWant) {
+		return fmt.Errorf("type %v incompatible with %v", tt, ttWant)
+	}
+	switch src {
+	case "Equifax":
+		*t.Value = 0
+	case "Experian":
+		*t.Value = 1
+	case "TransUnion":
+		*t.Value = 2
+	default:
+		return fmt.Errorf("label %s not in enum src/v.io/x/mojo/transcoder/internal.CreditAgency", src)
+	}
+
+	return nil
+}
+
+type ExperianRating int
+
+const (
+	ExperianRatingGood ExperianRating = iota
+	ExperianRatingBad
+)
+
+// ExperianRatingAll holds all labels for ExperianRating.
+var ExperianRatingAll = [...]ExperianRating{ExperianRatingGood, ExperianRatingBad}
+
+// ExperianRatingFromString creates a ExperianRating from a string label.
+func ExperianRatingFromString(label string) (x ExperianRating, err error) {
+	err = x.Set(label)
+	return
+}
+
+// Set assigns label to x.
+func (x *ExperianRating) Set(label string) error {
+	switch label {
+	case "Good", "good":
+		*x = ExperianRatingGood
+		return nil
+	case "Bad", "bad":
+		*x = ExperianRatingBad
+		return nil
+	}
+	*x = -1
+	return fmt.Errorf("unknown label %q in internal.ExperianRating", label)
+}
+
+// String returns the string label of x.
+func (x ExperianRating) String() string {
+	switch x {
+	case ExperianRatingGood:
+		return "Good"
+	case ExperianRatingBad:
+		return "Bad"
+	}
+	return ""
+}
+
+func (ExperianRating) __VDLReflect(struct {
+	Name string `vdl:"src/v.io/x/mojo/transcoder/internal.ExperianRating"`
+	Enum struct{ Good, Bad string }
+}) {
+}
+
+func (m *ExperianRating) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	if err := t.FromEnumLabel((*m).String(), tt); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *ExperianRating) MakeVDLTarget() vdl.Target {
+	return &ExperianRatingTarget{Value: m}
+}
+
+type ExperianRatingTarget struct {
+	Value *ExperianRating
+	vdl.TargetBase
+}
+
+func (t *ExperianRatingTarget) FromEnumLabel(src string, tt *vdl.Type) error {
+
+	if ttWant := vdl.TypeOf((*ExperianRating)(nil)); !vdl.Compatible(tt, ttWant) {
+		return fmt.Errorf("type %v incompatible with %v", tt, ttWant)
+	}
+	switch src {
+	case "Good":
+		*t.Value = 0
+	case "Bad":
+		*t.Value = 1
+	default:
+		return fmt.Errorf("label %s not in enum src/v.io/x/mojo/transcoder/internal.ExperianRating", src)
+	}
+
+	return nil
+}
+
+type EquifaxCreditReport struct {
+	Rating byte
+}
+
+func (EquifaxCreditReport) __VDLReflect(struct {
+	Name string `vdl:"src/v.io/x/mojo/transcoder/internal.EquifaxCreditReport"`
+}) {
+}
+
+func (m *EquifaxCreditReport) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Rating")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget3.FromUint(uint64(m.Rating), tt.NonOptional().Field(0).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+			return err
+		}
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *EquifaxCreditReport) MakeVDLTarget() vdl.Target {
+	return &EquifaxCreditReportTarget{Value: m}
+}
+
+type EquifaxCreditReportTarget struct {
+	Value        *EquifaxCreditReport
+	ratingTarget vdl.ByteTarget
+	vdl.TargetBase
+	vdl.FieldsTargetBase
+}
+
+func (t *EquifaxCreditReportTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
+
+	if ttWant := vdl.TypeOf((*EquifaxCreditReport)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
+		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
+	}
+	return t, nil
+}
+func (t *EquifaxCreditReportTarget) StartField(name string) (key, field vdl.Target, _ error) {
+	switch name {
+	case "Rating":
+		t.ratingTarget.Value = &t.Value.Rating
+		target, err := &t.ratingTarget, error(nil)
+		return nil, target, err
+	default:
+		return nil, nil, fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/internal.EquifaxCreditReport", name)
+	}
+}
+func (t *EquifaxCreditReportTarget) FinishField(_, _ vdl.Target) error {
+	return nil
+}
+func (t *EquifaxCreditReportTarget) FinishFields(_ vdl.FieldsTarget) error {
+
+	return nil
+}
+
+type ExperianCreditReport struct {
+	Rating ExperianRating
+}
+
+func (ExperianCreditReport) __VDLReflect(struct {
+	Name string `vdl:"src/v.io/x/mojo/transcoder/internal.ExperianCreditReport"`
+}) {
+}
+
+func (m *ExperianCreditReport) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Rating")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+
+		if err := m.Rating.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+			return err
+		}
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *ExperianCreditReport) MakeVDLTarget() vdl.Target {
+	return &ExperianCreditReportTarget{Value: m}
+}
+
+type ExperianCreditReportTarget struct {
+	Value        *ExperianCreditReport
+	ratingTarget ExperianRatingTarget
+	vdl.TargetBase
+	vdl.FieldsTargetBase
+}
+
+func (t *ExperianCreditReportTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
+
+	if ttWant := vdl.TypeOf((*ExperianCreditReport)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
+		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
+	}
+	return t, nil
+}
+func (t *ExperianCreditReportTarget) StartField(name string) (key, field vdl.Target, _ error) {
+	switch name {
+	case "Rating":
+		t.ratingTarget.Value = &t.Value.Rating
+		target, err := &t.ratingTarget, error(nil)
+		return nil, target, err
+	default:
+		return nil, nil, fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/internal.ExperianCreditReport", name)
+	}
+}
+func (t *ExperianCreditReportTarget) FinishField(_, _ vdl.Target) error {
+	return nil
+}
+func (t *ExperianCreditReportTarget) FinishFields(_ vdl.FieldsTarget) error {
+
+	return nil
+}
+
+type TransUnionCreditReport struct {
+	Rating int16
+}
+
+func (TransUnionCreditReport) __VDLReflect(struct {
+	Name string `vdl:"src/v.io/x/mojo/transcoder/internal.TransUnionCreditReport"`
+}) {
+}
+
+func (m *TransUnionCreditReport) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Rating")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget3.FromInt(int64(m.Rating), tt.NonOptional().Field(0).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+			return err
+		}
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *TransUnionCreditReport) MakeVDLTarget() vdl.Target {
+	return &TransUnionCreditReportTarget{Value: m}
+}
+
+type TransUnionCreditReportTarget struct {
+	Value        *TransUnionCreditReport
+	ratingTarget vdl.Int16Target
+	vdl.TargetBase
+	vdl.FieldsTargetBase
+}
+
+func (t *TransUnionCreditReportTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
+
+	if ttWant := vdl.TypeOf((*TransUnionCreditReport)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
+		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
+	}
+	return t, nil
+}
+func (t *TransUnionCreditReportTarget) StartField(name string) (key, field vdl.Target, _ error) {
+	switch name {
+	case "Rating":
+		t.ratingTarget.Value = &t.Value.Rating
+		target, err := &t.ratingTarget, error(nil)
+		return nil, target, err
+	default:
+		return nil, nil, fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/internal.TransUnionCreditReport", name)
+	}
+}
+func (t *TransUnionCreditReportTarget) FinishField(_, _ vdl.Target) error {
+	return nil
+}
+func (t *TransUnionCreditReportTarget) FinishFields(_ vdl.FieldsTarget) error {
+
+	return nil
+}
+
+type (
+	// AgencyReport represents any single field of the AgencyReport union type.
+	AgencyReport interface {
+		// Index returns the field index.
+		Index() int
+		// Interface returns the field value as an interface.
+		Interface() interface{}
+		// Name returns the field name.
+		Name() string
+		// __VDLReflect describes the AgencyReport union type.
+		__VDLReflect(__AgencyReportReflect)
+		FillVDLTarget(vdl.Target, *vdl.Type) error
+	}
+	// AgencyReportEquifaxReport represents field EquifaxReport of the AgencyReport union type.
+	AgencyReportEquifaxReport struct{ Value EquifaxCreditReport }
+	// AgencyReportExperianReport represents field ExperianReport of the AgencyReport union type.
+	AgencyReportExperianReport struct{ Value ExperianCreditReport }
+	// AgencyReportTransUnionReport represents field TransUnionReport of the AgencyReport union type.
+	AgencyReportTransUnionReport struct{ Value TransUnionCreditReport }
+	// __AgencyReportReflect describes the AgencyReport union type.
+	__AgencyReportReflect struct {
+		Name  string `vdl:"src/v.io/x/mojo/transcoder/internal.AgencyReport"`
+		Type  AgencyReport
+		Union struct {
+			EquifaxReport    AgencyReportEquifaxReport
+			ExperianReport   AgencyReportExperianReport
+			TransUnionReport AgencyReportTransUnionReport
+		}
+	}
+)
+
+func (x AgencyReportEquifaxReport) Index() int                         { return 0 }
+func (x AgencyReportEquifaxReport) Interface() interface{}             { return x.Value }
+func (x AgencyReportEquifaxReport) Name() string                       { return "EquifaxReport" }
+func (x AgencyReportEquifaxReport) __VDLReflect(__AgencyReportReflect) {}
+
+func (m AgencyReportEquifaxReport) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("EquifaxReport")
+	if err != nil {
+		return err
+	}
+
+	if err := m.Value.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m AgencyReportEquifaxReport) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x AgencyReportExperianReport) Index() int                         { return 1 }
+func (x AgencyReportExperianReport) Interface() interface{}             { return x.Value }
+func (x AgencyReportExperianReport) Name() string                       { return "ExperianReport" }
+func (x AgencyReportExperianReport) __VDLReflect(__AgencyReportReflect) {}
+
+func (m AgencyReportExperianReport) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("ExperianReport")
+	if err != nil {
+		return err
+	}
+
+	if err := m.Value.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(1).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m AgencyReportExperianReport) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x AgencyReportTransUnionReport) Index() int                         { return 2 }
+func (x AgencyReportTransUnionReport) Interface() interface{}             { return x.Value }
+func (x AgencyReportTransUnionReport) Name() string                       { return "TransUnionReport" }
+func (x AgencyReportTransUnionReport) __VDLReflect(__AgencyReportReflect) {}
+
+func (m AgencyReportTransUnionReport) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("TransUnionReport")
+	if err != nil {
+		return err
+	}
+
+	if err := m.Value.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(2).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m AgencyReportTransUnionReport) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+type CreditReport struct {
+	Agency CreditAgency
+	Report AgencyReport
+}
+
+func (CreditReport) __VDLReflect(struct {
+	Name string `vdl:"src/v.io/x/mojo/transcoder/internal.CreditReport"`
+}) {
+}
+
+func (m *CreditReport) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Agency")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+
+		if err := m.Agency.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+			return err
+		}
+	}
+	keyTarget4, fieldTarget5, err := fieldsTarget1.StartField("Report")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+
+		unionValue6 := m.Report
+		if unionValue6 == nil {
+			unionValue6 = AgencyReportEquifaxReport{}
+		}
+		if err := unionValue6.FillVDLTarget(fieldTarget5, tt.NonOptional().Field(1).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget4, fieldTarget5); err != nil {
+			return err
+		}
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *CreditReport) MakeVDLTarget() vdl.Target {
+	return &CreditReportTarget{Value: m}
+}
+
+type CreditReportTarget struct {
+	Value        *CreditReport
+	agencyTarget CreditAgencyTarget
+
+	vdl.TargetBase
+	vdl.FieldsTargetBase
+}
+
+func (t *CreditReportTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
+
+	if ttWant := vdl.TypeOf((*CreditReport)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
+		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
+	}
+	return t, nil
+}
+func (t *CreditReportTarget) StartField(name string) (key, field vdl.Target, _ error) {
+	switch name {
+	case "Agency":
+		t.agencyTarget.Value = &t.Value.Agency
+		target, err := &t.agencyTarget, error(nil)
+		return nil, target, err
+	case "Report":
+		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Report))
+		return nil, target, err
+	default:
+		return nil, nil, fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/internal.CreditReport", name)
+	}
+}
+func (t *CreditReportTarget) FinishField(_, _ vdl.Target) error {
+	return nil
+}
+func (t *CreditReportTarget) FinishFields(_ vdl.FieldsTarget) error {
+
+	return nil
+}
+
+type Customer struct {
+	Name    string
+	Id      int64
+	Active  bool
+	Address AddressInfo
+	Credit  CreditReport
+}
+
+func (Customer) __VDLReflect(struct {
+	Name string `vdl:"src/v.io/x/mojo/transcoder/internal.Customer"`
+}) {
+}
+
+func (m *Customer) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Name")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget3.FromString(string(m.Name), tt.NonOptional().Field(0).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+			return err
+		}
+	}
+	keyTarget4, fieldTarget5, err := fieldsTarget1.StartField("Id")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget5.FromInt(int64(m.Id), tt.NonOptional().Field(1).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget4, fieldTarget5); err != nil {
+			return err
+		}
+	}
+	keyTarget6, fieldTarget7, err := fieldsTarget1.StartField("Active")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget7.FromBool(bool(m.Active), tt.NonOptional().Field(2).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget6, fieldTarget7); err != nil {
+			return err
+		}
+	}
+	keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("Address")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+
+		if err := m.Address.FillVDLTarget(fieldTarget9, tt.NonOptional().Field(3).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
+			return err
+		}
+	}
+	keyTarget10, fieldTarget11, err := fieldsTarget1.StartField("Credit")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+
+		if err := m.Credit.FillVDLTarget(fieldTarget11, tt.NonOptional().Field(4).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget10, fieldTarget11); err != nil {
+			return err
+		}
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *Customer) MakeVDLTarget() vdl.Target {
+	return &CustomerTarget{Value: m}
+}
+
+type CustomerTarget struct {
+	Value         *Customer
+	nameTarget    vdl.StringTarget
+	idTarget      vdl.Int64Target
+	activeTarget  vdl.BoolTarget
+	addressTarget AddressInfoTarget
+	creditTarget  CreditReportTarget
+	vdl.TargetBase
+	vdl.FieldsTargetBase
+}
+
+func (t *CustomerTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
+
+	if ttWant := vdl.TypeOf((*Customer)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
+		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
+	}
+	return t, nil
+}
+func (t *CustomerTarget) StartField(name string) (key, field vdl.Target, _ error) {
+	switch name {
+	case "Name":
+		t.nameTarget.Value = &t.Value.Name
+		target, err := &t.nameTarget, error(nil)
+		return nil, target, err
+	case "Id":
+		t.idTarget.Value = &t.Value.Id
+		target, err := &t.idTarget, error(nil)
+		return nil, target, err
+	case "Active":
+		t.activeTarget.Value = &t.Value.Active
+		target, err := &t.activeTarget, error(nil)
+		return nil, target, err
+	case "Address":
+		t.addressTarget.Value = &t.Value.Address
+		target, err := &t.addressTarget, error(nil)
+		return nil, target, err
+	case "Credit":
+		t.creditTarget.Value = &t.Value.Credit
+		target, err := &t.creditTarget, error(nil)
+		return nil, target, err
+	default:
+		return nil, nil, fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/internal.Customer", name)
+	}
+}
+func (t *CustomerTarget) FinishField(_, _ vdl.Target) error {
+	return nil
+}
+func (t *CustomerTarget) FinishFields(_ vdl.FieldsTarget) error {
+
+	return nil
+}
+
+var __VDLInitCalled bool
+
+// __VDLInit performs vdl initialization.  It is safe to call multiple times.
+// If you have an init ordering issue, just insert the following line verbatim
+// into your source files in this package, right after the "package foo" clause:
+//
+//    var _ = __VDLInit()
+//
+// The purpose of this function is to ensure that vdl initialization occurs in
+// the right order, and very early in the init sequence.  In particular, vdl
+// registration and package variable initialization needs to occur before
+// functions like vdl.TypeOf will work properly.
+//
+// This function returns a dummy value, so that it can be used to initialize the
+// first var in the file, to take advantage of Go's defined init order.
+func __VDLInit() struct{} {
+	if __VDLInitCalled {
+		return struct{}{}
+	}
+
+	// Register types.
+	vdl.Register((*AddressInfo)(nil))
+	vdl.Register((*CreditAgency)(nil))
+	vdl.Register((*ExperianRating)(nil))
+	vdl.Register((*EquifaxCreditReport)(nil))
+	vdl.Register((*ExperianCreditReport)(nil))
+	vdl.Register((*TransUnionCreditReport)(nil))
+	vdl.Register((*AgencyReport)(nil))
+	vdl.Register((*CreditReport)(nil))
+	vdl.Register((*Customer)(nil))
+
+	return struct{}{}
+}
diff --git a/go/src/v.io/x/mojo/transcoder/internal/perf_test.vdl.go b/go/src/v.io/x/mojo/transcoder/internal/perf_test.vdl.go
deleted file mode 100644
index 44d4a6b..0000000
--- a/go/src/v.io/x/mojo/transcoder/internal/perf_test.vdl.go
+++ /dev/null
@@ -1,777 +0,0 @@
-// Copyright 2015 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.
-
-// This file was auto-generated by the vanadium vdl tool.
-// Source: perf_test.vdl
-
-package internal
-
-import (
-	// VDL system imports
-	"fmt"
-	"v.io/v23/vdl"
-)
-
-type AddressInfo struct {
-	Street string
-	City   string
-	State  string
-	Zip    string
-}
-
-func (AddressInfo) __VDLReflect(struct {
-	Name string `vdl:"src/v.io/x/mojo/transcoder/internal.AddressInfo"`
-}) {
-}
-
-func (m *AddressInfo) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	if __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_AddressInfo == nil || __VDLTypeperf_test0 == nil {
-		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
-	}
-	fieldsTarget1, err := t.StartFields(tt)
-	if err != nil {
-		return err
-	}
-
-	var2 := (m.Street == "")
-	if !var2 {
-		keyTarget3, fieldTarget4, err := fieldsTarget1.StartField("Street")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget4.FromString(string(m.Street), vdl.StringType); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget3, fieldTarget4); err != nil {
-				return err
-			}
-		}
-	}
-	var5 := (m.City == "")
-	if !var5 {
-		keyTarget6, fieldTarget7, err := fieldsTarget1.StartField("City")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget7.FromString(string(m.City), vdl.StringType); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget6, fieldTarget7); err != nil {
-				return err
-			}
-		}
-	}
-	var8 := (m.State == "")
-	if !var8 {
-		keyTarget9, fieldTarget10, err := fieldsTarget1.StartField("State")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget10.FromString(string(m.State), vdl.StringType); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget9, fieldTarget10); err != nil {
-				return err
-			}
-		}
-	}
-	var11 := (m.Zip == "")
-	if !var11 {
-		keyTarget12, fieldTarget13, err := fieldsTarget1.StartField("Zip")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget13.FromString(string(m.Zip), vdl.StringType); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget12, fieldTarget13); err != nil {
-				return err
-			}
-		}
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m *AddressInfo) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m *AddressInfo) IsZero() bool {
-
-	var1 := (*m == AddressInfo{})
-	return var1
-}
-
-type CreditAgency int
-
-const (
-	CreditAgencyEquifax CreditAgency = iota
-	CreditAgencyExperian
-	CreditAgencyTransUnion
-)
-
-// CreditAgencyAll holds all labels for CreditAgency.
-var CreditAgencyAll = [...]CreditAgency{CreditAgencyEquifax, CreditAgencyExperian, CreditAgencyTransUnion}
-
-// CreditAgencyFromString creates a CreditAgency from a string label.
-func CreditAgencyFromString(label string) (x CreditAgency, err error) {
-	err = x.Set(label)
-	return
-}
-
-// Set assigns label to x.
-func (x *CreditAgency) Set(label string) error {
-	switch label {
-	case "Equifax", "equifax":
-		*x = CreditAgencyEquifax
-		return nil
-	case "Experian", "experian":
-		*x = CreditAgencyExperian
-		return nil
-	case "TransUnion", "transunion":
-		*x = CreditAgencyTransUnion
-		return nil
-	}
-	*x = -1
-	return fmt.Errorf("unknown label %q in internal.CreditAgency", label)
-}
-
-// String returns the string label of x.
-func (x CreditAgency) String() string {
-	switch x {
-	case CreditAgencyEquifax:
-		return "Equifax"
-	case CreditAgencyExperian:
-		return "Experian"
-	case CreditAgencyTransUnion:
-		return "TransUnion"
-	}
-	return ""
-}
-
-func (CreditAgency) __VDLReflect(struct {
-	Name string `vdl:"src/v.io/x/mojo/transcoder/internal.CreditAgency"`
-	Enum struct{ Equifax, Experian, TransUnion string }
-}) {
-}
-
-func (m CreditAgency) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-	if err := t.FromEnumLabel(m.String(), __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_CreditAgency); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m CreditAgency) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m CreditAgency) IsZero() bool {
-
-	var1 := (m == CreditAgencyEquifax)
-	return var1
-}
-
-type ExperianRating int
-
-const (
-	ExperianRatingGood ExperianRating = iota
-	ExperianRatingBad
-)
-
-// ExperianRatingAll holds all labels for ExperianRating.
-var ExperianRatingAll = [...]ExperianRating{ExperianRatingGood, ExperianRatingBad}
-
-// ExperianRatingFromString creates a ExperianRating from a string label.
-func ExperianRatingFromString(label string) (x ExperianRating, err error) {
-	err = x.Set(label)
-	return
-}
-
-// Set assigns label to x.
-func (x *ExperianRating) Set(label string) error {
-	switch label {
-	case "Good", "good":
-		*x = ExperianRatingGood
-		return nil
-	case "Bad", "bad":
-		*x = ExperianRatingBad
-		return nil
-	}
-	*x = -1
-	return fmt.Errorf("unknown label %q in internal.ExperianRating", label)
-}
-
-// String returns the string label of x.
-func (x ExperianRating) String() string {
-	switch x {
-	case ExperianRatingGood:
-		return "Good"
-	case ExperianRatingBad:
-		return "Bad"
-	}
-	return ""
-}
-
-func (ExperianRating) __VDLReflect(struct {
-	Name string `vdl:"src/v.io/x/mojo/transcoder/internal.ExperianRating"`
-	Enum struct{ Good, Bad string }
-}) {
-}
-
-func (m ExperianRating) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-	if err := t.FromEnumLabel(m.String(), __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_ExperianRating); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m ExperianRating) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m ExperianRating) IsZero() bool {
-
-	var1 := (m == ExperianRatingGood)
-	return var1
-}
-
-type EquifaxCreditReport struct {
-	Rating byte
-}
-
-func (EquifaxCreditReport) __VDLReflect(struct {
-	Name string `vdl:"src/v.io/x/mojo/transcoder/internal.EquifaxCreditReport"`
-}) {
-}
-
-func (m *EquifaxCreditReport) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	if __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_EquifaxCreditReport == nil || __VDLTypeperf_test1 == nil {
-		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
-	}
-	fieldsTarget1, err := t.StartFields(tt)
-	if err != nil {
-		return err
-	}
-
-	var2 := (m.Rating == byte(0))
-	if !var2 {
-		keyTarget3, fieldTarget4, err := fieldsTarget1.StartField("Rating")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget4.FromUint(uint64(m.Rating), vdl.ByteType); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget3, fieldTarget4); err != nil {
-				return err
-			}
-		}
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m *EquifaxCreditReport) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m *EquifaxCreditReport) IsZero() bool {
-
-	var1 := (*m == EquifaxCreditReport{})
-	return var1
-}
-
-type ExperianCreditReport struct {
-	Rating ExperianRating
-}
-
-func (ExperianCreditReport) __VDLReflect(struct {
-	Name string `vdl:"src/v.io/x/mojo/transcoder/internal.ExperianCreditReport"`
-}) {
-}
-
-func (m *ExperianCreditReport) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	if __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_ExperianCreditReport == nil || __VDLTypeperf_test2 == nil {
-		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
-	}
-	fieldsTarget1, err := t.StartFields(tt)
-	if err != nil {
-		return err
-	}
-
-	var2 := m.Rating.IsZero()
-	if !var2 {
-		keyTarget3, fieldTarget4, err := fieldsTarget1.StartField("Rating")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-
-			if err := m.Rating.FillVDLTarget(fieldTarget4, __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_ExperianRating); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget3, fieldTarget4); err != nil {
-				return err
-			}
-		}
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m *ExperianCreditReport) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m *ExperianCreditReport) IsZero() bool {
-
-	var1 := (*m == ExperianCreditReport{})
-	return var1
-}
-
-type TransUnionCreditReport struct {
-	Rating int16
-}
-
-func (TransUnionCreditReport) __VDLReflect(struct {
-	Name string `vdl:"src/v.io/x/mojo/transcoder/internal.TransUnionCreditReport"`
-}) {
-}
-
-func (m *TransUnionCreditReport) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	if __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_TransUnionCreditReport == nil || __VDLTypeperf_test3 == nil {
-		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
-	}
-	fieldsTarget1, err := t.StartFields(tt)
-	if err != nil {
-		return err
-	}
-
-	var2 := (m.Rating == int16(0))
-	if !var2 {
-		keyTarget3, fieldTarget4, err := fieldsTarget1.StartField("Rating")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget4.FromInt(int64(m.Rating), vdl.Int16Type); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget3, fieldTarget4); err != nil {
-				return err
-			}
-		}
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m *TransUnionCreditReport) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m *TransUnionCreditReport) IsZero() bool {
-
-	var1 := (*m == TransUnionCreditReport{})
-	return var1
-}
-
-type (
-	// AgencyReport represents any single field of the AgencyReport union type.
-	AgencyReport interface {
-		// Index returns the field index.
-		Index() int
-		// Interface returns the field value as an interface.
-		Interface() interface{}
-		// Name returns the field name.
-		Name() string
-		// __VDLReflect describes the AgencyReport union type.
-		__VDLReflect(__AgencyReportReflect)
-		FillVDLTarget(vdl.Target, *vdl.Type) error
-		IsZero() bool
-	}
-	// AgencyReportEquifaxReport represents field EquifaxReport of the AgencyReport union type.
-	AgencyReportEquifaxReport struct{ Value EquifaxCreditReport }
-	// AgencyReportExperianReport represents field ExperianReport of the AgencyReport union type.
-	AgencyReportExperianReport struct{ Value ExperianCreditReport }
-	// AgencyReportTransUnionReport represents field TransUnionReport of the AgencyReport union type.
-	AgencyReportTransUnionReport struct{ Value TransUnionCreditReport }
-	// __AgencyReportReflect describes the AgencyReport union type.
-	__AgencyReportReflect struct {
-		Name  string `vdl:"src/v.io/x/mojo/transcoder/internal.AgencyReport"`
-		Type  AgencyReport
-		Union struct {
-			EquifaxReport    AgencyReportEquifaxReport
-			ExperianReport   AgencyReportExperianReport
-			TransUnionReport AgencyReportTransUnionReport
-		}
-	}
-)
-
-func (x AgencyReportEquifaxReport) Index() int                         { return 0 }
-func (x AgencyReportEquifaxReport) Interface() interface{}             { return x.Value }
-func (x AgencyReportEquifaxReport) Name() string                       { return "EquifaxReport" }
-func (x AgencyReportEquifaxReport) __VDLReflect(__AgencyReportReflect) {}
-
-func (m AgencyReportEquifaxReport) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_AgencyReport)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("EquifaxReport")
-	if err != nil {
-		return err
-	}
-
-	if err := m.Value.FillVDLTarget(fieldTarget3, __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_EquifaxCreditReport); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m AgencyReportEquifaxReport) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m AgencyReportEquifaxReport) IsZero() bool {
-
-	var1 := (m == AgencyReport(AgencyReportEquifaxReport{}))
-	return var1
-}
-
-func (x AgencyReportExperianReport) Index() int                         { return 1 }
-func (x AgencyReportExperianReport) Interface() interface{}             { return x.Value }
-func (x AgencyReportExperianReport) Name() string                       { return "ExperianReport" }
-func (x AgencyReportExperianReport) __VDLReflect(__AgencyReportReflect) {}
-
-func (m AgencyReportExperianReport) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_AgencyReport)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("ExperianReport")
-	if err != nil {
-		return err
-	}
-
-	if err := m.Value.FillVDLTarget(fieldTarget3, __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_ExperianCreditReport); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m AgencyReportExperianReport) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m AgencyReportExperianReport) IsZero() bool {
-
-	var1 := (m == AgencyReport(AgencyReportEquifaxReport{}))
-	return var1
-}
-
-func (x AgencyReportTransUnionReport) Index() int                         { return 2 }
-func (x AgencyReportTransUnionReport) Interface() interface{}             { return x.Value }
-func (x AgencyReportTransUnionReport) Name() string                       { return "TransUnionReport" }
-func (x AgencyReportTransUnionReport) __VDLReflect(__AgencyReportReflect) {}
-
-func (m AgencyReportTransUnionReport) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_AgencyReport)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("TransUnionReport")
-	if err != nil {
-		return err
-	}
-
-	if err := m.Value.FillVDLTarget(fieldTarget3, __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_TransUnionCreditReport); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m AgencyReportTransUnionReport) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m AgencyReportTransUnionReport) IsZero() bool {
-
-	var1 := (m == AgencyReport(AgencyReportEquifaxReport{}))
-	return var1
-}
-
-type CreditReport struct {
-	Agency CreditAgency
-	Report AgencyReport
-}
-
-func (CreditReport) __VDLReflect(struct {
-	Name string `vdl:"src/v.io/x/mojo/transcoder/internal.CreditReport"`
-}) {
-}
-
-func (m *CreditReport) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	if __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_CreditReport == nil || __VDLTypeperf_test4 == nil {
-		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
-	}
-	fieldsTarget1, err := t.StartFields(tt)
-	if err != nil {
-		return err
-	}
-
-	var2 := m.Agency.IsZero()
-	if !var2 {
-		keyTarget3, fieldTarget4, err := fieldsTarget1.StartField("Agency")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-
-			if err := m.Agency.FillVDLTarget(fieldTarget4, __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_CreditAgency); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget3, fieldTarget4); err != nil {
-				return err
-			}
-		}
-	}
-	var5 := m.Report.IsZero()
-	if !var5 {
-		keyTarget6, fieldTarget7, err := fieldsTarget1.StartField("Report")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-
-			unionValue8 := m.Report
-			if unionValue8 == nil {
-				unionValue8 = AgencyReportEquifaxReport{}
-			}
-			if err := unionValue8.FillVDLTarget(fieldTarget7, __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_AgencyReport); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget6, fieldTarget7); err != nil {
-				return err
-			}
-		}
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m *CreditReport) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m *CreditReport) IsZero() bool {
-
-	var1 := (*m == CreditReport{
-		Report: AgencyReportEquifaxReport{},
-	})
-	return var1
-}
-
-type Customer struct {
-	Name    string
-	Id      int64
-	Active  bool
-	Address AddressInfo
-	Credit  CreditReport
-}
-
-func (Customer) __VDLReflect(struct {
-	Name string `vdl:"src/v.io/x/mojo/transcoder/internal.Customer"`
-}) {
-}
-
-func (m *Customer) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	if __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_Customer == nil || __VDLTypeperf_test5 == nil {
-		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
-	}
-	fieldsTarget1, err := t.StartFields(tt)
-	if err != nil {
-		return err
-	}
-
-	var2 := (m.Name == "")
-	if !var2 {
-		keyTarget3, fieldTarget4, err := fieldsTarget1.StartField("Name")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget4.FromString(string(m.Name), vdl.StringType); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget3, fieldTarget4); err != nil {
-				return err
-			}
-		}
-	}
-	var5 := (m.Id == int64(0))
-	if !var5 {
-		keyTarget6, fieldTarget7, err := fieldsTarget1.StartField("Id")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget7.FromInt(int64(m.Id), vdl.Int64Type); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget6, fieldTarget7); err != nil {
-				return err
-			}
-		}
-	}
-	var8 := (m.Active == false)
-	if !var8 {
-		keyTarget9, fieldTarget10, err := fieldsTarget1.StartField("Active")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget10.FromBool(bool(m.Active), vdl.BoolType); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget9, fieldTarget10); err != nil {
-				return err
-			}
-		}
-	}
-	var11 := m.Address.IsZero()
-	if !var11 {
-		keyTarget12, fieldTarget13, err := fieldsTarget1.StartField("Address")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-
-			if err := m.Address.FillVDLTarget(fieldTarget13, __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_AddressInfo); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget12, fieldTarget13); err != nil {
-				return err
-			}
-		}
-	}
-	var14 := m.Credit.IsZero()
-	if !var14 {
-		keyTarget15, fieldTarget16, err := fieldsTarget1.StartField("Credit")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-
-			if err := m.Credit.FillVDLTarget(fieldTarget16, __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_CreditReport); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget15, fieldTarget16); err != nil {
-				return err
-			}
-		}
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m *Customer) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m *Customer) IsZero() bool {
-
-	var1 := (*m == Customer{
-		Credit: CreditReport{
-			Report: AgencyReportEquifaxReport{},
-		},
-	})
-	return var1
-}
-
-func init() {
-	vdl.Register((*AddressInfo)(nil))
-	vdl.Register((*CreditAgency)(nil))
-	vdl.Register((*ExperianRating)(nil))
-	vdl.Register((*EquifaxCreditReport)(nil))
-	vdl.Register((*ExperianCreditReport)(nil))
-	vdl.Register((*TransUnionCreditReport)(nil))
-	vdl.Register((*AgencyReport)(nil))
-	vdl.Register((*CreditReport)(nil))
-	vdl.Register((*Customer)(nil))
-}
-
-var __VDLTypeperf_test0 *vdl.Type = vdl.TypeOf((*AddressInfo)(nil))
-var __VDLTypeperf_test4 *vdl.Type = vdl.TypeOf((*CreditReport)(nil))
-var __VDLTypeperf_test5 *vdl.Type = vdl.TypeOf((*Customer)(nil))
-var __VDLTypeperf_test1 *vdl.Type = vdl.TypeOf((*EquifaxCreditReport)(nil))
-var __VDLTypeperf_test2 *vdl.Type = vdl.TypeOf((*ExperianCreditReport)(nil))
-var __VDLTypeperf_test3 *vdl.Type = vdl.TypeOf((*TransUnionCreditReport)(nil))
-var __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_AddressInfo *vdl.Type = vdl.TypeOf(AddressInfo{})
-var __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_AgencyReport *vdl.Type = vdl.TypeOf(AgencyReport(AgencyReportEquifaxReport{}))
-var __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_CreditAgency *vdl.Type = vdl.TypeOf(CreditAgencyEquifax)
-var __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_CreditReport *vdl.Type = vdl.TypeOf(CreditReport{
-	Report: AgencyReportEquifaxReport{},
-})
-var __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_Customer *vdl.Type = vdl.TypeOf(Customer{
-	Credit: CreditReport{
-		Report: AgencyReportEquifaxReport{},
-	},
-})
-var __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_EquifaxCreditReport *vdl.Type = vdl.TypeOf(EquifaxCreditReport{})
-var __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_ExperianCreditReport *vdl.Type = vdl.TypeOf(ExperianCreditReport{})
-var __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_ExperianRating *vdl.Type = vdl.TypeOf(ExperianRatingGood)
-var __VDLType_perf_test_src_v_io_x_mojo_transcoder_internal_TransUnionCreditReport *vdl.Type = vdl.TypeOf(TransUnionCreditReport{})
-
-func __VDLEnsureNativeBuilt_perf_test() {
-}
diff --git a/go/src/v.io/x/mojo/transcoder/testtypes/testtypes.vdl.go b/go/src/v.io/x/mojo/transcoder/testtypes/testtypes.vdl.go
new file mode 100644
index 0000000..cd71ff0
--- /dev/null
+++ b/go/src/v.io/x/mojo/transcoder/testtypes/testtypes.vdl.go
@@ -0,0 +1,1566 @@
+// Copyright 2015 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.
+
+// This file was auto-generated by the vanadium vdl tool.
+// Package: testtypes
+
+package testtypes
+
+import (
+	"fmt"
+	"reflect"
+	"v.io/v23/vdl"
+)
+
+var _ = __VDLInit() // Must be first; see __VDLInit comments for details.
+
+//////////////////////////////////////////////////
+// Type definitions
+
+type AnEnum int
+
+const (
+	AnEnumFirst AnEnum = iota
+	AnEnumSecond
+)
+
+// AnEnumAll holds all labels for AnEnum.
+var AnEnumAll = [...]AnEnum{AnEnumFirst, AnEnumSecond}
+
+// AnEnumFromString creates a AnEnum from a string label.
+func AnEnumFromString(label string) (x AnEnum, err error) {
+	err = x.Set(label)
+	return
+}
+
+// Set assigns label to x.
+func (x *AnEnum) Set(label string) error {
+	switch label {
+	case "First", "first":
+		*x = AnEnumFirst
+		return nil
+	case "Second", "second":
+		*x = AnEnumSecond
+		return nil
+	}
+	*x = -1
+	return fmt.Errorf("unknown label %q in testtypes.AnEnum", label)
+}
+
+// String returns the string label of x.
+func (x AnEnum) String() string {
+	switch x {
+	case AnEnumFirst:
+		return "First"
+	case AnEnumSecond:
+		return "Second"
+	}
+	return ""
+}
+
+func (AnEnum) __VDLReflect(struct {
+	Name string `vdl:"src/v.io/x/mojo/transcoder/testtypes.AnEnum"`
+	Enum struct{ First, Second string }
+}) {
+}
+
+func (m *AnEnum) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	if err := t.FromEnumLabel((*m).String(), tt); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *AnEnum) MakeVDLTarget() vdl.Target {
+	return &AnEnumTarget{Value: m}
+}
+
+type AnEnumTarget struct {
+	Value *AnEnum
+	vdl.TargetBase
+}
+
+func (t *AnEnumTarget) FromEnumLabel(src string, tt *vdl.Type) error {
+
+	if ttWant := vdl.TypeOf((*AnEnum)(nil)); !vdl.Compatible(tt, ttWant) {
+		return fmt.Errorf("type %v incompatible with %v", tt, ttWant)
+	}
+	switch src {
+	case "First":
+		*t.Value = 0
+	case "Second":
+		*t.Value = 1
+	default:
+		return fmt.Errorf("label %s not in enum src/v.io/x/mojo/transcoder/testtypes.AnEnum", src)
+	}
+
+	return nil
+}
+
+type (
+	// PodUnion represents any single field of the PodUnion union type.
+	PodUnion interface {
+		// Index returns the field index.
+		Index() int
+		// Interface returns the field value as an interface.
+		Interface() interface{}
+		// Name returns the field name.
+		Name() string
+		// __VDLReflect describes the PodUnion union type.
+		__VDLReflect(__PodUnionReflect)
+		FillVDLTarget(vdl.Target, *vdl.Type) error
+	}
+	// PodUnionFInt8 represents field FInt8 of the PodUnion union type.
+	PodUnionFInt8 struct{ Value int8 }
+	// PodUnionFInt8Other represents field FInt8Other of the PodUnion union type.
+	PodUnionFInt8Other struct{ Value int8 }
+	// PodUnionFUint8 represents field FUint8 of the PodUnion union type.
+	PodUnionFUint8 struct{ Value byte }
+	// PodUnionFInt16 represents field FInt16 of the PodUnion union type.
+	PodUnionFInt16 struct{ Value int16 }
+	// PodUnionFUint16 represents field FUint16 of the PodUnion union type.
+	PodUnionFUint16 struct{ Value uint16 }
+	// PodUnionFint32 represents field Fint32 of the PodUnion union type.
+	PodUnionFint32 struct{ Value int32 }
+	// PodUnionFuint32 represents field Fuint32 of the PodUnion union type.
+	PodUnionFuint32 struct{ Value uint32 }
+	// PodUnionFInt64 represents field FInt64 of the PodUnion union type.
+	PodUnionFInt64 struct{ Value int64 }
+	// PodUnionFUint64 represents field FUint64 of the PodUnion union type.
+	PodUnionFUint64 struct{ Value uint64 }
+	// PodUnionFFloat represents field FFloat of the PodUnion union type.
+	PodUnionFFloat struct{ Value float32 }
+	// PodUnionFDouble represents field FDouble of the PodUnion union type.
+	PodUnionFDouble struct{ Value float64 }
+	// PodUnionFBool represents field FBool of the PodUnion union type.
+	PodUnionFBool struct{ Value bool }
+	// PodUnionFEnum represents field FEnum of the PodUnion union type.
+	PodUnionFEnum struct{ Value AnEnum }
+	// __PodUnionReflect describes the PodUnion union type.
+	__PodUnionReflect struct {
+		Name  string `vdl:"src/v.io/x/mojo/transcoder/testtypes.PodUnion"`
+		Type  PodUnion
+		Union struct {
+			FInt8      PodUnionFInt8
+			FInt8Other PodUnionFInt8Other
+			FUint8     PodUnionFUint8
+			FInt16     PodUnionFInt16
+			FUint16    PodUnionFUint16
+			Fint32     PodUnionFint32
+			Fuint32    PodUnionFuint32
+			FInt64     PodUnionFInt64
+			FUint64    PodUnionFUint64
+			FFloat     PodUnionFFloat
+			FDouble    PodUnionFDouble
+			FBool      PodUnionFBool
+			FEnum      PodUnionFEnum
+		}
+	}
+)
+
+func (x PodUnionFInt8) Index() int                     { return 0 }
+func (x PodUnionFInt8) Interface() interface{}         { return x.Value }
+func (x PodUnionFInt8) Name() string                   { return "FInt8" }
+func (x PodUnionFInt8) __VDLReflect(__PodUnionReflect) {}
+
+func (m PodUnionFInt8) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FInt8")
+	if err != nil {
+		return err
+	}
+	if err := fieldTarget3.FromInt(int64(m.Value), tt.NonOptional().Field(0).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m PodUnionFInt8) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x PodUnionFInt8Other) Index() int                     { return 1 }
+func (x PodUnionFInt8Other) Interface() interface{}         { return x.Value }
+func (x PodUnionFInt8Other) Name() string                   { return "FInt8Other" }
+func (x PodUnionFInt8Other) __VDLReflect(__PodUnionReflect) {}
+
+func (m PodUnionFInt8Other) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FInt8Other")
+	if err != nil {
+		return err
+	}
+	if err := fieldTarget3.FromInt(int64(m.Value), tt.NonOptional().Field(1).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m PodUnionFInt8Other) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x PodUnionFUint8) Index() int                     { return 2 }
+func (x PodUnionFUint8) Interface() interface{}         { return x.Value }
+func (x PodUnionFUint8) Name() string                   { return "FUint8" }
+func (x PodUnionFUint8) __VDLReflect(__PodUnionReflect) {}
+
+func (m PodUnionFUint8) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FUint8")
+	if err != nil {
+		return err
+	}
+	if err := fieldTarget3.FromUint(uint64(m.Value), tt.NonOptional().Field(2).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m PodUnionFUint8) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x PodUnionFInt16) Index() int                     { return 3 }
+func (x PodUnionFInt16) Interface() interface{}         { return x.Value }
+func (x PodUnionFInt16) Name() string                   { return "FInt16" }
+func (x PodUnionFInt16) __VDLReflect(__PodUnionReflect) {}
+
+func (m PodUnionFInt16) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FInt16")
+	if err != nil {
+		return err
+	}
+	if err := fieldTarget3.FromInt(int64(m.Value), tt.NonOptional().Field(3).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m PodUnionFInt16) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x PodUnionFUint16) Index() int                     { return 4 }
+func (x PodUnionFUint16) Interface() interface{}         { return x.Value }
+func (x PodUnionFUint16) Name() string                   { return "FUint16" }
+func (x PodUnionFUint16) __VDLReflect(__PodUnionReflect) {}
+
+func (m PodUnionFUint16) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FUint16")
+	if err != nil {
+		return err
+	}
+	if err := fieldTarget3.FromUint(uint64(m.Value), tt.NonOptional().Field(4).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m PodUnionFUint16) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x PodUnionFint32) Index() int                     { return 5 }
+func (x PodUnionFint32) Interface() interface{}         { return x.Value }
+func (x PodUnionFint32) Name() string                   { return "Fint32" }
+func (x PodUnionFint32) __VDLReflect(__PodUnionReflect) {}
+
+func (m PodUnionFint32) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Fint32")
+	if err != nil {
+		return err
+	}
+	if err := fieldTarget3.FromInt(int64(m.Value), tt.NonOptional().Field(5).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m PodUnionFint32) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x PodUnionFuint32) Index() int                     { return 6 }
+func (x PodUnionFuint32) Interface() interface{}         { return x.Value }
+func (x PodUnionFuint32) Name() string                   { return "Fuint32" }
+func (x PodUnionFuint32) __VDLReflect(__PodUnionReflect) {}
+
+func (m PodUnionFuint32) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Fuint32")
+	if err != nil {
+		return err
+	}
+	if err := fieldTarget3.FromUint(uint64(m.Value), tt.NonOptional().Field(6).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m PodUnionFuint32) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x PodUnionFInt64) Index() int                     { return 7 }
+func (x PodUnionFInt64) Interface() interface{}         { return x.Value }
+func (x PodUnionFInt64) Name() string                   { return "FInt64" }
+func (x PodUnionFInt64) __VDLReflect(__PodUnionReflect) {}
+
+func (m PodUnionFInt64) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FInt64")
+	if err != nil {
+		return err
+	}
+	if err := fieldTarget3.FromInt(int64(m.Value), tt.NonOptional().Field(7).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m PodUnionFInt64) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x PodUnionFUint64) Index() int                     { return 8 }
+func (x PodUnionFUint64) Interface() interface{}         { return x.Value }
+func (x PodUnionFUint64) Name() string                   { return "FUint64" }
+func (x PodUnionFUint64) __VDLReflect(__PodUnionReflect) {}
+
+func (m PodUnionFUint64) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FUint64")
+	if err != nil {
+		return err
+	}
+	if err := fieldTarget3.FromUint(uint64(m.Value), tt.NonOptional().Field(8).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m PodUnionFUint64) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x PodUnionFFloat) Index() int                     { return 9 }
+func (x PodUnionFFloat) Interface() interface{}         { return x.Value }
+func (x PodUnionFFloat) Name() string                   { return "FFloat" }
+func (x PodUnionFFloat) __VDLReflect(__PodUnionReflect) {}
+
+func (m PodUnionFFloat) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FFloat")
+	if err != nil {
+		return err
+	}
+	if err := fieldTarget3.FromFloat(float64(m.Value), tt.NonOptional().Field(9).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m PodUnionFFloat) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x PodUnionFDouble) Index() int                     { return 10 }
+func (x PodUnionFDouble) Interface() interface{}         { return x.Value }
+func (x PodUnionFDouble) Name() string                   { return "FDouble" }
+func (x PodUnionFDouble) __VDLReflect(__PodUnionReflect) {}
+
+func (m PodUnionFDouble) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FDouble")
+	if err != nil {
+		return err
+	}
+	if err := fieldTarget3.FromFloat(float64(m.Value), tt.NonOptional().Field(10).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m PodUnionFDouble) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x PodUnionFBool) Index() int                     { return 11 }
+func (x PodUnionFBool) Interface() interface{}         { return x.Value }
+func (x PodUnionFBool) Name() string                   { return "FBool" }
+func (x PodUnionFBool) __VDLReflect(__PodUnionReflect) {}
+
+func (m PodUnionFBool) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FBool")
+	if err != nil {
+		return err
+	}
+	if err := fieldTarget3.FromBool(bool(m.Value), tt.NonOptional().Field(11).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m PodUnionFBool) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x PodUnionFEnum) Index() int                     { return 12 }
+func (x PodUnionFEnum) Interface() interface{}         { return x.Value }
+func (x PodUnionFEnum) Name() string                   { return "FEnum" }
+func (x PodUnionFEnum) __VDLReflect(__PodUnionReflect) {}
+
+func (m PodUnionFEnum) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FEnum")
+	if err != nil {
+		return err
+	}
+
+	if err := m.Value.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(12).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m PodUnionFEnum) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+type PodUnionWrapper struct {
+	PodUnion PodUnion
+}
+
+func (PodUnionWrapper) __VDLReflect(struct {
+	Name string `vdl:"src/v.io/x/mojo/transcoder/testtypes.PodUnionWrapper"`
+}) {
+}
+
+func (m *PodUnionWrapper) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("PodUnion")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+
+		unionValue4 := m.PodUnion
+		if unionValue4 == nil {
+			unionValue4 = PodUnionFInt8{}
+		}
+		if err := unionValue4.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+			return err
+		}
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *PodUnionWrapper) MakeVDLTarget() vdl.Target {
+	return &PodUnionWrapperTarget{Value: m}
+}
+
+type PodUnionWrapperTarget struct {
+	Value *PodUnionWrapper
+
+	vdl.TargetBase
+	vdl.FieldsTargetBase
+}
+
+func (t *PodUnionWrapperTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
+
+	if ttWant := vdl.TypeOf((*PodUnionWrapper)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
+		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
+	}
+	return t, nil
+}
+func (t *PodUnionWrapperTarget) StartField(name string) (key, field vdl.Target, _ error) {
+	switch name {
+	case "PodUnion":
+		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.PodUnion))
+		return nil, target, err
+	default:
+		return nil, nil, fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/testtypes.PodUnionWrapper", name)
+	}
+}
+func (t *PodUnionWrapperTarget) FinishField(_, _ vdl.Target) error {
+	return nil
+}
+func (t *PodUnionWrapperTarget) FinishFields(_ vdl.FieldsTarget) error {
+
+	return nil
+}
+
+type DummyStruct struct {
+	FInt8 int8
+}
+
+func (DummyStruct) __VDLReflect(struct {
+	Name string `vdl:"src/v.io/x/mojo/transcoder/testtypes.DummyStruct"`
+}) {
+}
+
+func (m *DummyStruct) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FInt8")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget3.FromInt(int64(m.FInt8), tt.NonOptional().Field(0).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+			return err
+		}
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *DummyStruct) MakeVDLTarget() vdl.Target {
+	return &DummyStructTarget{Value: m}
+}
+
+type DummyStructTarget struct {
+	Value       *DummyStruct
+	fInt8Target vdl.Int8Target
+	vdl.TargetBase
+	vdl.FieldsTargetBase
+}
+
+func (t *DummyStructTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
+
+	if ttWant := vdl.TypeOf((*DummyStruct)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
+		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
+	}
+	return t, nil
+}
+func (t *DummyStructTarget) StartField(name string) (key, field vdl.Target, _ error) {
+	switch name {
+	case "FInt8":
+		t.fInt8Target.Value = &t.Value.FInt8
+		target, err := &t.fInt8Target, error(nil)
+		return nil, target, err
+	default:
+		return nil, nil, fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/testtypes.DummyStruct", name)
+	}
+}
+func (t *DummyStructTarget) FinishField(_, _ vdl.Target) error {
+	return nil
+}
+func (t *DummyStructTarget) FinishFields(_ vdl.FieldsTarget) error {
+
+	return nil
+}
+
+type (
+	// ObjectUnion represents any single field of the ObjectUnion union type.
+	ObjectUnion interface {
+		// Index returns the field index.
+		Index() int
+		// Interface returns the field value as an interface.
+		Interface() interface{}
+		// Name returns the field name.
+		Name() string
+		// __VDLReflect describes the ObjectUnion union type.
+		__VDLReflect(__ObjectUnionReflect)
+		FillVDLTarget(vdl.Target, *vdl.Type) error
+	}
+	// ObjectUnionFInt8 represents field FInt8 of the ObjectUnion union type.
+	ObjectUnionFInt8 struct{ Value int8 }
+	// ObjectUnionFString represents field FString of the ObjectUnion union type.
+	ObjectUnionFString struct{ Value string }
+	// ObjectUnionFDummy represents field FDummy of the ObjectUnion union type.
+	ObjectUnionFDummy struct{ Value DummyStruct }
+	// ObjectUnionFNullable represents field FNullable of the ObjectUnion union type.
+	ObjectUnionFNullable struct{ Value *DummyStruct }
+	// ObjectUnionFArrayInt8 represents field FArrayInt8 of the ObjectUnion union type.
+	ObjectUnionFArrayInt8 struct{ Value []int8 }
+	// ObjectUnionFMapInt8 represents field FMapInt8 of the ObjectUnion union type.
+	ObjectUnionFMapInt8 struct{ Value map[string]int8 }
+	// ObjectUnionFPodUnion represents field FPodUnion of the ObjectUnion union type.
+	ObjectUnionFPodUnion struct{ Value PodUnion }
+	// __ObjectUnionReflect describes the ObjectUnion union type.
+	__ObjectUnionReflect struct {
+		Name  string `vdl:"src/v.io/x/mojo/transcoder/testtypes.ObjectUnion"`
+		Type  ObjectUnion
+		Union struct {
+			FInt8      ObjectUnionFInt8
+			FString    ObjectUnionFString
+			FDummy     ObjectUnionFDummy
+			FNullable  ObjectUnionFNullable
+			FArrayInt8 ObjectUnionFArrayInt8
+			FMapInt8   ObjectUnionFMapInt8
+			FPodUnion  ObjectUnionFPodUnion
+		}
+	}
+)
+
+func (x ObjectUnionFInt8) Index() int                        { return 0 }
+func (x ObjectUnionFInt8) Interface() interface{}            { return x.Value }
+func (x ObjectUnionFInt8) Name() string                      { return "FInt8" }
+func (x ObjectUnionFInt8) __VDLReflect(__ObjectUnionReflect) {}
+
+func (m ObjectUnionFInt8) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FInt8")
+	if err != nil {
+		return err
+	}
+	if err := fieldTarget3.FromInt(int64(m.Value), tt.NonOptional().Field(0).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m ObjectUnionFInt8) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x ObjectUnionFString) Index() int                        { return 1 }
+func (x ObjectUnionFString) Interface() interface{}            { return x.Value }
+func (x ObjectUnionFString) Name() string                      { return "FString" }
+func (x ObjectUnionFString) __VDLReflect(__ObjectUnionReflect) {}
+
+func (m ObjectUnionFString) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FString")
+	if err != nil {
+		return err
+	}
+	if err := fieldTarget3.FromString(string(m.Value), tt.NonOptional().Field(1).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m ObjectUnionFString) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x ObjectUnionFDummy) Index() int                        { return 2 }
+func (x ObjectUnionFDummy) Interface() interface{}            { return x.Value }
+func (x ObjectUnionFDummy) Name() string                      { return "FDummy" }
+func (x ObjectUnionFDummy) __VDLReflect(__ObjectUnionReflect) {}
+
+func (m ObjectUnionFDummy) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FDummy")
+	if err != nil {
+		return err
+	}
+
+	if err := m.Value.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(2).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m ObjectUnionFDummy) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x ObjectUnionFNullable) Index() int                        { return 3 }
+func (x ObjectUnionFNullable) Interface() interface{}            { return x.Value }
+func (x ObjectUnionFNullable) Name() string                      { return "FNullable" }
+func (x ObjectUnionFNullable) __VDLReflect(__ObjectUnionReflect) {}
+
+func (m ObjectUnionFNullable) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FNullable")
+	if err != nil {
+		return err
+	}
+
+	if m.Value == nil {
+		if err := fieldTarget3.FromNil(tt.NonOptional().Field(3).Type); err != nil {
+			return err
+		}
+	} else {
+		if err := m.Value.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(3).Type); err != nil {
+			return err
+		}
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m ObjectUnionFNullable) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x ObjectUnionFArrayInt8) Index() int                        { return 4 }
+func (x ObjectUnionFArrayInt8) Interface() interface{}            { return x.Value }
+func (x ObjectUnionFArrayInt8) Name() string                      { return "FArrayInt8" }
+func (x ObjectUnionFArrayInt8) __VDLReflect(__ObjectUnionReflect) {}
+
+func (m ObjectUnionFArrayInt8) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FArrayInt8")
+	if err != nil {
+		return err
+	}
+
+	listTarget4, err := fieldTarget3.StartList(tt.NonOptional().Field(4).Type, len(m.Value))
+	if err != nil {
+		return err
+	}
+	for i, elem6 := range m.Value {
+		elemTarget5, err := listTarget4.StartElem(i)
+		if err != nil {
+			return err
+		}
+		if err := elemTarget5.FromInt(int64(elem6), tt.NonOptional().Field(4).Type.Elem()); err != nil {
+			return err
+		}
+		if err := listTarget4.FinishElem(elemTarget5); err != nil {
+			return err
+		}
+	}
+	if err := fieldTarget3.FinishList(listTarget4); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m ObjectUnionFArrayInt8) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x ObjectUnionFMapInt8) Index() int                        { return 5 }
+func (x ObjectUnionFMapInt8) Interface() interface{}            { return x.Value }
+func (x ObjectUnionFMapInt8) Name() string                      { return "FMapInt8" }
+func (x ObjectUnionFMapInt8) __VDLReflect(__ObjectUnionReflect) {}
+
+func (m ObjectUnionFMapInt8) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FMapInt8")
+	if err != nil {
+		return err
+	}
+
+	mapTarget4, err := fieldTarget3.StartMap(tt.NonOptional().Field(5).Type, len(m.Value))
+	if err != nil {
+		return err
+	}
+	for key6, value8 := range m.Value {
+		keyTarget5, err := mapTarget4.StartKey()
+		if err != nil {
+			return err
+		}
+		if err := keyTarget5.FromString(string(key6), tt.NonOptional().Field(5).Type.Key()); err != nil {
+			return err
+		}
+		valueTarget7, err := mapTarget4.FinishKeyStartField(keyTarget5)
+		if err != nil {
+			return err
+		}
+		if err := valueTarget7.FromInt(int64(value8), tt.NonOptional().Field(5).Type.Elem()); err != nil {
+			return err
+		}
+		if err := mapTarget4.FinishField(keyTarget5, valueTarget7); err != nil {
+			return err
+		}
+	}
+	if err := fieldTarget3.FinishMap(mapTarget4); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m ObjectUnionFMapInt8) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+func (x ObjectUnionFPodUnion) Index() int                        { return 6 }
+func (x ObjectUnionFPodUnion) Interface() interface{}            { return x.Value }
+func (x ObjectUnionFPodUnion) Name() string                      { return "FPodUnion" }
+func (x ObjectUnionFPodUnion) __VDLReflect(__ObjectUnionReflect) {}
+
+func (m ObjectUnionFPodUnion) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FPodUnion")
+	if err != nil {
+		return err
+	}
+
+	unionValue4 := m.Value
+	if unionValue4 == nil {
+		unionValue4 = PodUnionFInt8{}
+	}
+	if err := unionValue4.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(6).Type); err != nil {
+		return err
+	}
+	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+		return err
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (m ObjectUnionFPodUnion) MakeVDLTarget() vdl.Target {
+	return nil
+}
+
+type ObjectUnionWrapper struct {
+	ObjectUnion ObjectUnion
+}
+
+func (ObjectUnionWrapper) __VDLReflect(struct {
+	Name string `vdl:"src/v.io/x/mojo/transcoder/testtypes.ObjectUnionWrapper"`
+}) {
+}
+
+func (m *ObjectUnionWrapper) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("ObjectUnion")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+
+		unionValue4 := m.ObjectUnion
+		if unionValue4 == nil {
+			unionValue4 = ObjectUnionFInt8{}
+		}
+		if err := unionValue4.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+			return err
+		}
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *ObjectUnionWrapper) MakeVDLTarget() vdl.Target {
+	return &ObjectUnionWrapperTarget{Value: m}
+}
+
+type ObjectUnionWrapperTarget struct {
+	Value *ObjectUnionWrapper
+
+	vdl.TargetBase
+	vdl.FieldsTargetBase
+}
+
+func (t *ObjectUnionWrapperTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
+
+	if ttWant := vdl.TypeOf((*ObjectUnionWrapper)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
+		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
+	}
+	return t, nil
+}
+func (t *ObjectUnionWrapperTarget) StartField(name string) (key, field vdl.Target, _ error) {
+	switch name {
+	case "ObjectUnion":
+		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.ObjectUnion))
+		return nil, target, err
+	default:
+		return nil, nil, fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/testtypes.ObjectUnionWrapper", name)
+	}
+}
+func (t *ObjectUnionWrapperTarget) FinishField(_, _ vdl.Target) error {
+	return nil
+}
+func (t *ObjectUnionWrapperTarget) FinishFields(_ vdl.FieldsTarget) error {
+
+	return nil
+}
+
+type Rect struct {
+	X      int32
+	Y      int32
+	Width  int32
+	Height int32
+}
+
+func (Rect) __VDLReflect(struct {
+	Name string `vdl:"src/v.io/x/mojo/transcoder/testtypes.Rect"`
+}) {
+}
+
+func (m *Rect) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("X")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget3.FromInt(int64(m.X), tt.NonOptional().Field(0).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+			return err
+		}
+	}
+	keyTarget4, fieldTarget5, err := fieldsTarget1.StartField("Y")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget5.FromInt(int64(m.Y), tt.NonOptional().Field(1).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget4, fieldTarget5); err != nil {
+			return err
+		}
+	}
+	keyTarget6, fieldTarget7, err := fieldsTarget1.StartField("Width")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget7.FromInt(int64(m.Width), tt.NonOptional().Field(2).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget6, fieldTarget7); err != nil {
+			return err
+		}
+	}
+	keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("Height")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget9.FromInt(int64(m.Height), tt.NonOptional().Field(3).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
+			return err
+		}
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *Rect) MakeVDLTarget() vdl.Target {
+	return &RectTarget{Value: m}
+}
+
+type RectTarget struct {
+	Value        *Rect
+	xTarget      vdl.Int32Target
+	yTarget      vdl.Int32Target
+	widthTarget  vdl.Int32Target
+	heightTarget vdl.Int32Target
+	vdl.TargetBase
+	vdl.FieldsTargetBase
+}
+
+func (t *RectTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
+
+	if ttWant := vdl.TypeOf((*Rect)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
+		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
+	}
+	return t, nil
+}
+func (t *RectTarget) StartField(name string) (key, field vdl.Target, _ error) {
+	switch name {
+	case "X":
+		t.xTarget.Value = &t.Value.X
+		target, err := &t.xTarget, error(nil)
+		return nil, target, err
+	case "Y":
+		t.yTarget.Value = &t.Value.Y
+		target, err := &t.yTarget, error(nil)
+		return nil, target, err
+	case "Width":
+		t.widthTarget.Value = &t.Value.Width
+		target, err := &t.widthTarget, error(nil)
+		return nil, target, err
+	case "Height":
+		t.heightTarget.Value = &t.Value.Height
+		target, err := &t.heightTarget, error(nil)
+		return nil, target, err
+	default:
+		return nil, nil, fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/testtypes.Rect", name)
+	}
+}
+func (t *RectTarget) FinishField(_, _ vdl.Target) error {
+	return nil
+}
+func (t *RectTarget) FinishFields(_ vdl.FieldsTarget) error {
+
+	return nil
+}
+
+type MultiVersionStruct struct {
+	FInt32  int32
+	FRect   Rect
+	FString string
+	FArray  []int8
+	FBool   bool
+	FInt16  int16
+}
+
+func (MultiVersionStruct) __VDLReflect(struct {
+	Name string `vdl:"src/v.io/x/mojo/transcoder/testtypes.MultiVersionStruct"`
+}) {
+}
+
+func (m *MultiVersionStruct) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FInt32")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget3.FromInt(int64(m.FInt32), tt.NonOptional().Field(0).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+			return err
+		}
+	}
+	keyTarget4, fieldTarget5, err := fieldsTarget1.StartField("FRect")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+
+		if err := m.FRect.FillVDLTarget(fieldTarget5, tt.NonOptional().Field(1).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget4, fieldTarget5); err != nil {
+			return err
+		}
+	}
+	keyTarget6, fieldTarget7, err := fieldsTarget1.StartField("FString")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget7.FromString(string(m.FString), tt.NonOptional().Field(2).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget6, fieldTarget7); err != nil {
+			return err
+		}
+	}
+	keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("FArray")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+
+		listTarget10, err := fieldTarget9.StartList(tt.NonOptional().Field(3).Type, len(m.FArray))
+		if err != nil {
+			return err
+		}
+		for i, elem12 := range m.FArray {
+			elemTarget11, err := listTarget10.StartElem(i)
+			if err != nil {
+				return err
+			}
+			if err := elemTarget11.FromInt(int64(elem12), tt.NonOptional().Field(3).Type.Elem()); err != nil {
+				return err
+			}
+			if err := listTarget10.FinishElem(elemTarget11); err != nil {
+				return err
+			}
+		}
+		if err := fieldTarget9.FinishList(listTarget10); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
+			return err
+		}
+	}
+	keyTarget13, fieldTarget14, err := fieldsTarget1.StartField("FBool")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget14.FromBool(bool(m.FBool), tt.NonOptional().Field(4).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget13, fieldTarget14); err != nil {
+			return err
+		}
+	}
+	keyTarget15, fieldTarget16, err := fieldsTarget1.StartField("FInt16")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget16.FromInt(int64(m.FInt16), tt.NonOptional().Field(5).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget15, fieldTarget16); err != nil {
+			return err
+		}
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *MultiVersionStruct) MakeVDLTarget() vdl.Target {
+	return &MultiVersionStructTarget{Value: m}
+}
+
+type MultiVersionStructTarget struct {
+	Value         *MultiVersionStruct
+	fInt32Target  vdl.Int32Target
+	fRectTarget   RectTarget
+	fStringTarget vdl.StringTarget
+	fArrayTarget  unnamed_5b5d696e7438Target
+	fBoolTarget   vdl.BoolTarget
+	fInt16Target  vdl.Int16Target
+	vdl.TargetBase
+	vdl.FieldsTargetBase
+}
+
+func (t *MultiVersionStructTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
+
+	if ttWant := vdl.TypeOf((*MultiVersionStruct)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
+		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
+	}
+	return t, nil
+}
+func (t *MultiVersionStructTarget) StartField(name string) (key, field vdl.Target, _ error) {
+	switch name {
+	case "FInt32":
+		t.fInt32Target.Value = &t.Value.FInt32
+		target, err := &t.fInt32Target, error(nil)
+		return nil, target, err
+	case "FRect":
+		t.fRectTarget.Value = &t.Value.FRect
+		target, err := &t.fRectTarget, error(nil)
+		return nil, target, err
+	case "FString":
+		t.fStringTarget.Value = &t.Value.FString
+		target, err := &t.fStringTarget, error(nil)
+		return nil, target, err
+	case "FArray":
+		t.fArrayTarget.Value = &t.Value.FArray
+		target, err := &t.fArrayTarget, error(nil)
+		return nil, target, err
+	case "FBool":
+		t.fBoolTarget.Value = &t.Value.FBool
+		target, err := &t.fBoolTarget, error(nil)
+		return nil, target, err
+	case "FInt16":
+		t.fInt16Target.Value = &t.Value.FInt16
+		target, err := &t.fInt16Target, error(nil)
+		return nil, target, err
+	default:
+		return nil, nil, fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/testtypes.MultiVersionStruct", name)
+	}
+}
+func (t *MultiVersionStructTarget) FinishField(_, _ vdl.Target) error {
+	return nil
+}
+func (t *MultiVersionStructTarget) FinishFields(_ vdl.FieldsTarget) error {
+
+	return nil
+}
+
+// []int8
+type unnamed_5b5d696e7438Target struct {
+	Value      *[]int8
+	elemTarget vdl.Int8Target
+	vdl.TargetBase
+	vdl.ListTargetBase
+}
+
+func (t *unnamed_5b5d696e7438Target) StartList(tt *vdl.Type, len int) (vdl.ListTarget, error) {
+
+	if ttWant := vdl.TypeOf((*[]int8)(nil)); !vdl.Compatible(tt, ttWant) {
+		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
+	}
+	if cap(*t.Value) < len {
+		*t.Value = make([]int8, len)
+	} else {
+		*t.Value = (*t.Value)[:len]
+	}
+	return t, nil
+}
+func (t *unnamed_5b5d696e7438Target) StartElem(index int) (elem vdl.Target, _ error) {
+	t.elemTarget.Value = &(*t.Value)[index]
+	target, err := &t.elemTarget, error(nil)
+	return target, err
+}
+func (t *unnamed_5b5d696e7438Target) FinishElem(elem vdl.Target) error {
+	return nil
+}
+func (t *unnamed_5b5d696e7438Target) FinishList(elem vdl.ListTarget) error {
+
+	return nil
+}
+
+type MultiVersionStructV3 struct {
+	FInt32  int32
+	FRect   Rect
+	FString string
+}
+
+func (MultiVersionStructV3) __VDLReflect(struct {
+	Name string `vdl:"src/v.io/x/mojo/transcoder/testtypes.MultiVersionStructV3"`
+}) {
+}
+
+func (m *MultiVersionStructV3) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
+	fieldsTarget1, err := t.StartFields(tt)
+	if err != nil {
+		return err
+	}
+
+	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FInt32")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget3.FromInt(int64(m.FInt32), tt.NonOptional().Field(0).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
+			return err
+		}
+	}
+	keyTarget4, fieldTarget5, err := fieldsTarget1.StartField("FRect")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+
+		if err := m.FRect.FillVDLTarget(fieldTarget5, tt.NonOptional().Field(1).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget4, fieldTarget5); err != nil {
+			return err
+		}
+	}
+	keyTarget6, fieldTarget7, err := fieldsTarget1.StartField("FString")
+	if err != vdl.ErrFieldNoExist && err != nil {
+		return err
+	}
+	if err != vdl.ErrFieldNoExist {
+		if err := fieldTarget7.FromString(string(m.FString), tt.NonOptional().Field(2).Type); err != nil {
+			return err
+		}
+		if err := fieldsTarget1.FinishField(keyTarget6, fieldTarget7); err != nil {
+			return err
+		}
+	}
+	if err := t.FinishFields(fieldsTarget1); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (m *MultiVersionStructV3) MakeVDLTarget() vdl.Target {
+	return &MultiVersionStructV3Target{Value: m}
+}
+
+type MultiVersionStructV3Target struct {
+	Value         *MultiVersionStructV3
+	fInt32Target  vdl.Int32Target
+	fRectTarget   RectTarget
+	fStringTarget vdl.StringTarget
+	vdl.TargetBase
+	vdl.FieldsTargetBase
+}
+
+func (t *MultiVersionStructV3Target) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
+
+	if ttWant := vdl.TypeOf((*MultiVersionStructV3)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
+		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
+	}
+	return t, nil
+}
+func (t *MultiVersionStructV3Target) StartField(name string) (key, field vdl.Target, _ error) {
+	switch name {
+	case "FInt32":
+		t.fInt32Target.Value = &t.Value.FInt32
+		target, err := &t.fInt32Target, error(nil)
+		return nil, target, err
+	case "FRect":
+		t.fRectTarget.Value = &t.Value.FRect
+		target, err := &t.fRectTarget, error(nil)
+		return nil, target, err
+	case "FString":
+		t.fStringTarget.Value = &t.Value.FString
+		target, err := &t.fStringTarget, error(nil)
+		return nil, target, err
+	default:
+		return nil, nil, fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/testtypes.MultiVersionStructV3", name)
+	}
+}
+func (t *MultiVersionStructV3Target) FinishField(_, _ vdl.Target) error {
+	return nil
+}
+func (t *MultiVersionStructV3Target) FinishFields(_ vdl.FieldsTarget) error {
+
+	return nil
+}
+
+var __VDLInitCalled bool
+
+// __VDLInit performs vdl initialization.  It is safe to call multiple times.
+// If you have an init ordering issue, just insert the following line verbatim
+// into your source files in this package, right after the "package foo" clause:
+//
+//    var _ = __VDLInit()
+//
+// The purpose of this function is to ensure that vdl initialization occurs in
+// the right order, and very early in the init sequence.  In particular, vdl
+// registration and package variable initialization needs to occur before
+// functions like vdl.TypeOf will work properly.
+//
+// This function returns a dummy value, so that it can be used to initialize the
+// first var in the file, to take advantage of Go's defined init order.
+func __VDLInit() struct{} {
+	if __VDLInitCalled {
+		return struct{}{}
+	}
+
+	// Register types.
+	vdl.Register((*AnEnum)(nil))
+	vdl.Register((*PodUnion)(nil))
+	vdl.Register((*PodUnionWrapper)(nil))
+	vdl.Register((*DummyStruct)(nil))
+	vdl.Register((*ObjectUnion)(nil))
+	vdl.Register((*ObjectUnionWrapper)(nil))
+	vdl.Register((*Rect)(nil))
+	vdl.Register((*MultiVersionStruct)(nil))
+	vdl.Register((*MultiVersionStructV3)(nil))
+
+	return struct{}{}
+}
diff --git a/go/src/v.io/x/mojo/transcoder/testtypes/testtypes_test.vdl.go b/go/src/v.io/x/mojo/transcoder/testtypes/testtypes_test.vdl.go
deleted file mode 100644
index fbd017d..0000000
--- a/go/src/v.io/x/mojo/transcoder/testtypes/testtypes_test.vdl.go
+++ /dev/null
@@ -1,1553 +0,0 @@
-// Copyright 2015 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.
-
-// This file was auto-generated by the vanadium vdl tool.
-// Source: testtypes_test.vdl
-
-package testtypes
-
-import (
-	// VDL system imports
-	"fmt"
-	"v.io/v23/vdl"
-)
-
-type AnEnum int
-
-const (
-	AnEnumFirst AnEnum = iota
-	AnEnumSecond
-)
-
-// AnEnumAll holds all labels for AnEnum.
-var AnEnumAll = [...]AnEnum{AnEnumFirst, AnEnumSecond}
-
-// AnEnumFromString creates a AnEnum from a string label.
-func AnEnumFromString(label string) (x AnEnum, err error) {
-	err = x.Set(label)
-	return
-}
-
-// Set assigns label to x.
-func (x *AnEnum) Set(label string) error {
-	switch label {
-	case "First", "first":
-		*x = AnEnumFirst
-		return nil
-	case "Second", "second":
-		*x = AnEnumSecond
-		return nil
-	}
-	*x = -1
-	return fmt.Errorf("unknown label %q in testtypes.AnEnum", label)
-}
-
-// String returns the string label of x.
-func (x AnEnum) String() string {
-	switch x {
-	case AnEnumFirst:
-		return "First"
-	case AnEnumSecond:
-		return "Second"
-	}
-	return ""
-}
-
-func (AnEnum) __VDLReflect(struct {
-	Name string `vdl:"src/v.io/x/mojo/transcoder/testtypes.AnEnum"`
-	Enum struct{ First, Second string }
-}) {
-}
-
-func (m AnEnum) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-	if err := t.FromEnumLabel(m.String(), __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_AnEnum); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m AnEnum) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m AnEnum) IsZero() bool {
-
-	var1 := (m == AnEnumFirst)
-	return var1
-}
-
-type (
-	// PodUnion represents any single field of the PodUnion union type.
-	PodUnion interface {
-		// Index returns the field index.
-		Index() int
-		// Interface returns the field value as an interface.
-		Interface() interface{}
-		// Name returns the field name.
-		Name() string
-		// __VDLReflect describes the PodUnion union type.
-		__VDLReflect(__PodUnionReflect)
-		FillVDLTarget(vdl.Target, *vdl.Type) error
-		IsZero() bool
-	}
-	// PodUnionFInt8 represents field FInt8 of the PodUnion union type.
-	PodUnionFInt8 struct{ Value int8 }
-	// PodUnionFInt8Other represents field FInt8Other of the PodUnion union type.
-	PodUnionFInt8Other struct{ Value int8 }
-	// PodUnionFUint8 represents field FUint8 of the PodUnion union type.
-	PodUnionFUint8 struct{ Value byte }
-	// PodUnionFInt16 represents field FInt16 of the PodUnion union type.
-	PodUnionFInt16 struct{ Value int16 }
-	// PodUnionFUint16 represents field FUint16 of the PodUnion union type.
-	PodUnionFUint16 struct{ Value uint16 }
-	// PodUnionFint32 represents field Fint32 of the PodUnion union type.
-	PodUnionFint32 struct{ Value int32 }
-	// PodUnionFuint32 represents field Fuint32 of the PodUnion union type.
-	PodUnionFuint32 struct{ Value uint32 }
-	// PodUnionFInt64 represents field FInt64 of the PodUnion union type.
-	PodUnionFInt64 struct{ Value int64 }
-	// PodUnionFUint64 represents field FUint64 of the PodUnion union type.
-	PodUnionFUint64 struct{ Value uint64 }
-	// PodUnionFFloat represents field FFloat of the PodUnion union type.
-	PodUnionFFloat struct{ Value float32 }
-	// PodUnionFDouble represents field FDouble of the PodUnion union type.
-	PodUnionFDouble struct{ Value float64 }
-	// PodUnionFBool represents field FBool of the PodUnion union type.
-	PodUnionFBool struct{ Value bool }
-	// PodUnionFEnum represents field FEnum of the PodUnion union type.
-	PodUnionFEnum struct{ Value AnEnum }
-	// __PodUnionReflect describes the PodUnion union type.
-	__PodUnionReflect struct {
-		Name  string `vdl:"src/v.io/x/mojo/transcoder/testtypes.PodUnion"`
-		Type  PodUnion
-		Union struct {
-			FInt8      PodUnionFInt8
-			FInt8Other PodUnionFInt8Other
-			FUint8     PodUnionFUint8
-			FInt16     PodUnionFInt16
-			FUint16    PodUnionFUint16
-			Fint32     PodUnionFint32
-			Fuint32    PodUnionFuint32
-			FInt64     PodUnionFInt64
-			FUint64    PodUnionFUint64
-			FFloat     PodUnionFFloat
-			FDouble    PodUnionFDouble
-			FBool      PodUnionFBool
-			FEnum      PodUnionFEnum
-		}
-	}
-)
-
-func (x PodUnionFInt8) Index() int                     { return 0 }
-func (x PodUnionFInt8) Interface() interface{}         { return x.Value }
-func (x PodUnionFInt8) Name() string                   { return "FInt8" }
-func (x PodUnionFInt8) __VDLReflect(__PodUnionReflect) {}
-
-func (m PodUnionFInt8) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FInt8")
-	if err != nil {
-		return err
-	}
-	if err := fieldTarget3.FromInt(int64(m.Value), vdl.Int8Type); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m PodUnionFInt8) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m PodUnionFInt8) IsZero() bool {
-
-	var1 := (m == PodUnion(PodUnionFInt8{}))
-	return var1
-}
-
-func (x PodUnionFInt8Other) Index() int                     { return 1 }
-func (x PodUnionFInt8Other) Interface() interface{}         { return x.Value }
-func (x PodUnionFInt8Other) Name() string                   { return "FInt8Other" }
-func (x PodUnionFInt8Other) __VDLReflect(__PodUnionReflect) {}
-
-func (m PodUnionFInt8Other) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FInt8Other")
-	if err != nil {
-		return err
-	}
-	if err := fieldTarget3.FromInt(int64(m.Value), vdl.Int8Type); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m PodUnionFInt8Other) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m PodUnionFInt8Other) IsZero() bool {
-
-	var1 := (m == PodUnion(PodUnionFInt8{}))
-	return var1
-}
-
-func (x PodUnionFUint8) Index() int                     { return 2 }
-func (x PodUnionFUint8) Interface() interface{}         { return x.Value }
-func (x PodUnionFUint8) Name() string                   { return "FUint8" }
-func (x PodUnionFUint8) __VDLReflect(__PodUnionReflect) {}
-
-func (m PodUnionFUint8) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FUint8")
-	if err != nil {
-		return err
-	}
-	if err := fieldTarget3.FromUint(uint64(m.Value), vdl.ByteType); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m PodUnionFUint8) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m PodUnionFUint8) IsZero() bool {
-
-	var1 := (m == PodUnion(PodUnionFInt8{}))
-	return var1
-}
-
-func (x PodUnionFInt16) Index() int                     { return 3 }
-func (x PodUnionFInt16) Interface() interface{}         { return x.Value }
-func (x PodUnionFInt16) Name() string                   { return "FInt16" }
-func (x PodUnionFInt16) __VDLReflect(__PodUnionReflect) {}
-
-func (m PodUnionFInt16) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FInt16")
-	if err != nil {
-		return err
-	}
-	if err := fieldTarget3.FromInt(int64(m.Value), vdl.Int16Type); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m PodUnionFInt16) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m PodUnionFInt16) IsZero() bool {
-
-	var1 := (m == PodUnion(PodUnionFInt8{}))
-	return var1
-}
-
-func (x PodUnionFUint16) Index() int                     { return 4 }
-func (x PodUnionFUint16) Interface() interface{}         { return x.Value }
-func (x PodUnionFUint16) Name() string                   { return "FUint16" }
-func (x PodUnionFUint16) __VDLReflect(__PodUnionReflect) {}
-
-func (m PodUnionFUint16) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FUint16")
-	if err != nil {
-		return err
-	}
-	if err := fieldTarget3.FromUint(uint64(m.Value), vdl.Uint16Type); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m PodUnionFUint16) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m PodUnionFUint16) IsZero() bool {
-
-	var1 := (m == PodUnion(PodUnionFInt8{}))
-	return var1
-}
-
-func (x PodUnionFint32) Index() int                     { return 5 }
-func (x PodUnionFint32) Interface() interface{}         { return x.Value }
-func (x PodUnionFint32) Name() string                   { return "Fint32" }
-func (x PodUnionFint32) __VDLReflect(__PodUnionReflect) {}
-
-func (m PodUnionFint32) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Fint32")
-	if err != nil {
-		return err
-	}
-	if err := fieldTarget3.FromInt(int64(m.Value), vdl.Int32Type); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m PodUnionFint32) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m PodUnionFint32) IsZero() bool {
-
-	var1 := (m == PodUnion(PodUnionFInt8{}))
-	return var1
-}
-
-func (x PodUnionFuint32) Index() int                     { return 6 }
-func (x PodUnionFuint32) Interface() interface{}         { return x.Value }
-func (x PodUnionFuint32) Name() string                   { return "Fuint32" }
-func (x PodUnionFuint32) __VDLReflect(__PodUnionReflect) {}
-
-func (m PodUnionFuint32) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Fuint32")
-	if err != nil {
-		return err
-	}
-	if err := fieldTarget3.FromUint(uint64(m.Value), vdl.Uint32Type); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m PodUnionFuint32) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m PodUnionFuint32) IsZero() bool {
-
-	var1 := (m == PodUnion(PodUnionFInt8{}))
-	return var1
-}
-
-func (x PodUnionFInt64) Index() int                     { return 7 }
-func (x PodUnionFInt64) Interface() interface{}         { return x.Value }
-func (x PodUnionFInt64) Name() string                   { return "FInt64" }
-func (x PodUnionFInt64) __VDLReflect(__PodUnionReflect) {}
-
-func (m PodUnionFInt64) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FInt64")
-	if err != nil {
-		return err
-	}
-	if err := fieldTarget3.FromInt(int64(m.Value), vdl.Int64Type); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m PodUnionFInt64) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m PodUnionFInt64) IsZero() bool {
-
-	var1 := (m == PodUnion(PodUnionFInt8{}))
-	return var1
-}
-
-func (x PodUnionFUint64) Index() int                     { return 8 }
-func (x PodUnionFUint64) Interface() interface{}         { return x.Value }
-func (x PodUnionFUint64) Name() string                   { return "FUint64" }
-func (x PodUnionFUint64) __VDLReflect(__PodUnionReflect) {}
-
-func (m PodUnionFUint64) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FUint64")
-	if err != nil {
-		return err
-	}
-	if err := fieldTarget3.FromUint(uint64(m.Value), vdl.Uint64Type); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m PodUnionFUint64) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m PodUnionFUint64) IsZero() bool {
-
-	var1 := (m == PodUnion(PodUnionFInt8{}))
-	return var1
-}
-
-func (x PodUnionFFloat) Index() int                     { return 9 }
-func (x PodUnionFFloat) Interface() interface{}         { return x.Value }
-func (x PodUnionFFloat) Name() string                   { return "FFloat" }
-func (x PodUnionFFloat) __VDLReflect(__PodUnionReflect) {}
-
-func (m PodUnionFFloat) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FFloat")
-	if err != nil {
-		return err
-	}
-	if err := fieldTarget3.FromFloat(float64(m.Value), vdl.Float32Type); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m PodUnionFFloat) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m PodUnionFFloat) IsZero() bool {
-
-	var1 := (m == PodUnion(PodUnionFInt8{}))
-	return var1
-}
-
-func (x PodUnionFDouble) Index() int                     { return 10 }
-func (x PodUnionFDouble) Interface() interface{}         { return x.Value }
-func (x PodUnionFDouble) Name() string                   { return "FDouble" }
-func (x PodUnionFDouble) __VDLReflect(__PodUnionReflect) {}
-
-func (m PodUnionFDouble) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FDouble")
-	if err != nil {
-		return err
-	}
-	if err := fieldTarget3.FromFloat(float64(m.Value), vdl.Float64Type); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m PodUnionFDouble) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m PodUnionFDouble) IsZero() bool {
-
-	var1 := (m == PodUnion(PodUnionFInt8{}))
-	return var1
-}
-
-func (x PodUnionFBool) Index() int                     { return 11 }
-func (x PodUnionFBool) Interface() interface{}         { return x.Value }
-func (x PodUnionFBool) Name() string                   { return "FBool" }
-func (x PodUnionFBool) __VDLReflect(__PodUnionReflect) {}
-
-func (m PodUnionFBool) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FBool")
-	if err != nil {
-		return err
-	}
-	if err := fieldTarget3.FromBool(bool(m.Value), vdl.BoolType); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m PodUnionFBool) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m PodUnionFBool) IsZero() bool {
-
-	var1 := (m == PodUnion(PodUnionFInt8{}))
-	return var1
-}
-
-func (x PodUnionFEnum) Index() int                     { return 12 }
-func (x PodUnionFEnum) Interface() interface{}         { return x.Value }
-func (x PodUnionFEnum) Name() string                   { return "FEnum" }
-func (x PodUnionFEnum) __VDLReflect(__PodUnionReflect) {}
-
-func (m PodUnionFEnum) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FEnum")
-	if err != nil {
-		return err
-	}
-
-	if err := m.Value.FillVDLTarget(fieldTarget3, __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_AnEnum); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m PodUnionFEnum) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m PodUnionFEnum) IsZero() bool {
-
-	var1 := (m == PodUnion(PodUnionFInt8{}))
-	return var1
-}
-
-type PodUnionWrapper struct {
-	PodUnion PodUnion
-}
-
-func (PodUnionWrapper) __VDLReflect(struct {
-	Name string `vdl:"src/v.io/x/mojo/transcoder/testtypes.PodUnionWrapper"`
-}) {
-}
-
-func (m *PodUnionWrapper) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	if __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnionWrapper == nil || __VDLTypetesttypes_test0 == nil {
-		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
-	}
-	fieldsTarget1, err := t.StartFields(tt)
-	if err != nil {
-		return err
-	}
-
-	var2 := m.PodUnion.IsZero()
-	if !var2 {
-		keyTarget3, fieldTarget4, err := fieldsTarget1.StartField("PodUnion")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-
-			unionValue5 := m.PodUnion
-			if unionValue5 == nil {
-				unionValue5 = PodUnionFInt8{}
-			}
-			if err := unionValue5.FillVDLTarget(fieldTarget4, __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnion); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget3, fieldTarget4); err != nil {
-				return err
-			}
-		}
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m *PodUnionWrapper) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m *PodUnionWrapper) IsZero() bool {
-
-	var1 := (*m == PodUnionWrapper{
-		PodUnion: PodUnionFInt8{},
-	})
-	return var1
-}
-
-type DummyStruct struct {
-	FInt8 int8
-}
-
-func (DummyStruct) __VDLReflect(struct {
-	Name string `vdl:"src/v.io/x/mojo/transcoder/testtypes.DummyStruct"`
-}) {
-}
-
-func (m *DummyStruct) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	if __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_DummyStruct == nil || __VDLTypetesttypes_test1 == nil {
-		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
-	}
-	fieldsTarget1, err := t.StartFields(tt)
-	if err != nil {
-		return err
-	}
-
-	var2 := (m.FInt8 == int8(0))
-	if !var2 {
-		keyTarget3, fieldTarget4, err := fieldsTarget1.StartField("FInt8")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget4.FromInt(int64(m.FInt8), vdl.Int8Type); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget3, fieldTarget4); err != nil {
-				return err
-			}
-		}
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m *DummyStruct) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m *DummyStruct) IsZero() bool {
-
-	var1 := (*m == DummyStruct{})
-	return var1
-}
-
-type (
-	// ObjectUnion represents any single field of the ObjectUnion union type.
-	ObjectUnion interface {
-		// Index returns the field index.
-		Index() int
-		// Interface returns the field value as an interface.
-		Interface() interface{}
-		// Name returns the field name.
-		Name() string
-		// __VDLReflect describes the ObjectUnion union type.
-		__VDLReflect(__ObjectUnionReflect)
-		FillVDLTarget(vdl.Target, *vdl.Type) error
-		IsZero() bool
-	}
-	// ObjectUnionFInt8 represents field FInt8 of the ObjectUnion union type.
-	ObjectUnionFInt8 struct{ Value int8 }
-	// ObjectUnionFString represents field FString of the ObjectUnion union type.
-	ObjectUnionFString struct{ Value string }
-	// ObjectUnionFDummy represents field FDummy of the ObjectUnion union type.
-	ObjectUnionFDummy struct{ Value DummyStruct }
-	// ObjectUnionFNullable represents field FNullable of the ObjectUnion union type.
-	ObjectUnionFNullable struct{ Value *DummyStruct }
-	// ObjectUnionFArrayInt8 represents field FArrayInt8 of the ObjectUnion union type.
-	ObjectUnionFArrayInt8 struct{ Value []int8 }
-	// ObjectUnionFMapInt8 represents field FMapInt8 of the ObjectUnion union type.
-	ObjectUnionFMapInt8 struct{ Value map[string]int8 }
-	// ObjectUnionFPodUnion represents field FPodUnion of the ObjectUnion union type.
-	ObjectUnionFPodUnion struct{ Value PodUnion }
-	// __ObjectUnionReflect describes the ObjectUnion union type.
-	__ObjectUnionReflect struct {
-		Name  string `vdl:"src/v.io/x/mojo/transcoder/testtypes.ObjectUnion"`
-		Type  ObjectUnion
-		Union struct {
-			FInt8      ObjectUnionFInt8
-			FString    ObjectUnionFString
-			FDummy     ObjectUnionFDummy
-			FNullable  ObjectUnionFNullable
-			FArrayInt8 ObjectUnionFArrayInt8
-			FMapInt8   ObjectUnionFMapInt8
-			FPodUnion  ObjectUnionFPodUnion
-		}
-	}
-)
-
-func (x ObjectUnionFInt8) Index() int                        { return 0 }
-func (x ObjectUnionFInt8) Interface() interface{}            { return x.Value }
-func (x ObjectUnionFInt8) Name() string                      { return "FInt8" }
-func (x ObjectUnionFInt8) __VDLReflect(__ObjectUnionReflect) {}
-
-func (m ObjectUnionFInt8) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_ObjectUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FInt8")
-	if err != nil {
-		return err
-	}
-	if err := fieldTarget3.FromInt(int64(m.Value), vdl.Int8Type); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m ObjectUnionFInt8) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m ObjectUnionFInt8) IsZero() bool {
-
-	var2 := (m.Value == int8(0))
-	return var2
-}
-
-func (x ObjectUnionFString) Index() int                        { return 1 }
-func (x ObjectUnionFString) Interface() interface{}            { return x.Value }
-func (x ObjectUnionFString) Name() string                      { return "FString" }
-func (x ObjectUnionFString) __VDLReflect(__ObjectUnionReflect) {}
-
-func (m ObjectUnionFString) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_ObjectUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FString")
-	if err != nil {
-		return err
-	}
-	if err := fieldTarget3.FromString(string(m.Value), vdl.StringType); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m ObjectUnionFString) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m ObjectUnionFString) IsZero() bool {
-
-	var2 := (m.Value == "")
-	return var2
-}
-
-func (x ObjectUnionFDummy) Index() int                        { return 2 }
-func (x ObjectUnionFDummy) Interface() interface{}            { return x.Value }
-func (x ObjectUnionFDummy) Name() string                      { return "FDummy" }
-func (x ObjectUnionFDummy) __VDLReflect(__ObjectUnionReflect) {}
-
-func (m ObjectUnionFDummy) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_ObjectUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FDummy")
-	if err != nil {
-		return err
-	}
-
-	if err := m.Value.FillVDLTarget(fieldTarget3, __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_DummyStruct); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m ObjectUnionFDummy) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m ObjectUnionFDummy) IsZero() bool {
-
-	var2 := m.Value.IsZero()
-	return var2
-}
-
-func (x ObjectUnionFNullable) Index() int                        { return 3 }
-func (x ObjectUnionFNullable) Interface() interface{}            { return x.Value }
-func (x ObjectUnionFNullable) Name() string                      { return "FNullable" }
-func (x ObjectUnionFNullable) __VDLReflect(__ObjectUnionReflect) {}
-
-func (m ObjectUnionFNullable) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_ObjectUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FNullable")
-	if err != nil {
-		return err
-	}
-
-	if m.Value == nil {
-		if err := fieldTarget3.FromNil(__VDLTypetesttypes_test1); err != nil {
-			return err
-		}
-	} else {
-		if err := m.Value.FillVDLTarget(fieldTarget3, __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_DummyStruct); err != nil {
-			return err
-		}
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m ObjectUnionFNullable) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m ObjectUnionFNullable) IsZero() bool {
-
-	var2 := (m.Value == (*DummyStruct)(nil))
-	return var2
-}
-
-func (x ObjectUnionFArrayInt8) Index() int                        { return 4 }
-func (x ObjectUnionFArrayInt8) Interface() interface{}            { return x.Value }
-func (x ObjectUnionFArrayInt8) Name() string                      { return "FArrayInt8" }
-func (x ObjectUnionFArrayInt8) __VDLReflect(__ObjectUnionReflect) {}
-
-func (m ObjectUnionFArrayInt8) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_ObjectUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FArrayInt8")
-	if err != nil {
-		return err
-	}
-
-	listTarget4, err := fieldTarget3.StartList(__VDLTypetesttypes_test2, len(m.Value))
-	if err != nil {
-		return err
-	}
-	for i, elem6 := range m.Value {
-		elemTarget5, err := listTarget4.StartElem(i)
-		if err != nil {
-			return err
-		}
-		if err := elemTarget5.FromInt(int64(elem6), vdl.Int8Type); err != nil {
-			return err
-		}
-		if err := listTarget4.FinishElem(elemTarget5); err != nil {
-			return err
-		}
-	}
-	if err := fieldTarget3.FinishList(listTarget4); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m ObjectUnionFArrayInt8) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m ObjectUnionFArrayInt8) IsZero() bool {
-
-	var var2 bool
-	if len(m.Value) == 0 {
-		var2 = true
-	}
-	return var2
-}
-
-func (x ObjectUnionFMapInt8) Index() int                        { return 5 }
-func (x ObjectUnionFMapInt8) Interface() interface{}            { return x.Value }
-func (x ObjectUnionFMapInt8) Name() string                      { return "FMapInt8" }
-func (x ObjectUnionFMapInt8) __VDLReflect(__ObjectUnionReflect) {}
-
-func (m ObjectUnionFMapInt8) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_ObjectUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FMapInt8")
-	if err != nil {
-		return err
-	}
-
-	mapTarget4, err := fieldTarget3.StartMap(__VDLTypetesttypes_test3, len(m.Value))
-	if err != nil {
-		return err
-	}
-	for key6, value8 := range m.Value {
-		keyTarget5, err := mapTarget4.StartKey()
-		if err != nil {
-			return err
-		}
-		if err := keyTarget5.FromString(string(key6), vdl.StringType); err != nil {
-			return err
-		}
-		valueTarget7, err := mapTarget4.FinishKeyStartField(keyTarget5)
-		if err != nil {
-			return err
-		}
-		if err := valueTarget7.FromInt(int64(value8), vdl.Int8Type); err != nil {
-			return err
-		}
-		if err := mapTarget4.FinishField(keyTarget5, valueTarget7); err != nil {
-			return err
-		}
-	}
-	if err := fieldTarget3.FinishMap(mapTarget4); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m ObjectUnionFMapInt8) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m ObjectUnionFMapInt8) IsZero() bool {
-
-	var var2 bool
-	if len(m.Value) == 0 {
-		var2 = true
-	}
-	return var2
-}
-
-func (x ObjectUnionFPodUnion) Index() int                        { return 6 }
-func (x ObjectUnionFPodUnion) Interface() interface{}            { return x.Value }
-func (x ObjectUnionFPodUnion) Name() string                      { return "FPodUnion" }
-func (x ObjectUnionFPodUnion) __VDLReflect(__ObjectUnionReflect) {}
-
-func (m ObjectUnionFPodUnion) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	fieldsTarget1, err := t.StartFields(__VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_ObjectUnion)
-	if err != nil {
-		return err
-	}
-	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("FPodUnion")
-	if err != nil {
-		return err
-	}
-
-	unionValue4 := m.Value
-	if unionValue4 == nil {
-		unionValue4 = PodUnionFInt8{}
-	}
-	if err := unionValue4.FillVDLTarget(fieldTarget3, __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnion); err != nil {
-		return err
-	}
-	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
-		return err
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (m ObjectUnionFPodUnion) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m ObjectUnionFPodUnion) IsZero() bool {
-
-	var2 := m.Value.IsZero()
-	return var2
-}
-
-type ObjectUnionWrapper struct {
-	ObjectUnion ObjectUnion
-}
-
-func (ObjectUnionWrapper) __VDLReflect(struct {
-	Name string `vdl:"src/v.io/x/mojo/transcoder/testtypes.ObjectUnionWrapper"`
-}) {
-}
-
-func (m *ObjectUnionWrapper) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	if __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_ObjectUnionWrapper == nil || __VDLTypetesttypes_test4 == nil {
-		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
-	}
-	fieldsTarget1, err := t.StartFields(tt)
-	if err != nil {
-		return err
-	}
-
-	var2 := m.ObjectUnion.IsZero()
-	if !var2 {
-		keyTarget3, fieldTarget4, err := fieldsTarget1.StartField("ObjectUnion")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-
-			unionValue5 := m.ObjectUnion
-			if unionValue5 == nil {
-				unionValue5 = ObjectUnionFInt8{}
-			}
-			if err := unionValue5.FillVDLTarget(fieldTarget4, __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_ObjectUnion); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget3, fieldTarget4); err != nil {
-				return err
-			}
-		}
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m *ObjectUnionWrapper) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m *ObjectUnionWrapper) IsZero() bool {
-
-	var1 := true
-	var2 := m.ObjectUnion.IsZero()
-	var1 = var1 && var2
-	return var1
-}
-
-type Rect struct {
-	X      int32
-	Y      int32
-	Width  int32
-	Height int32
-}
-
-func (Rect) __VDLReflect(struct {
-	Name string `vdl:"src/v.io/x/mojo/transcoder/testtypes.Rect"`
-}) {
-}
-
-func (m *Rect) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	if __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_Rect == nil || __VDLTypetesttypes_test5 == nil {
-		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
-	}
-	fieldsTarget1, err := t.StartFields(tt)
-	if err != nil {
-		return err
-	}
-
-	var2 := (m.X == int32(0))
-	if !var2 {
-		keyTarget3, fieldTarget4, err := fieldsTarget1.StartField("X")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget4.FromInt(int64(m.X), vdl.Int32Type); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget3, fieldTarget4); err != nil {
-				return err
-			}
-		}
-	}
-	var5 := (m.Y == int32(0))
-	if !var5 {
-		keyTarget6, fieldTarget7, err := fieldsTarget1.StartField("Y")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget7.FromInt(int64(m.Y), vdl.Int32Type); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget6, fieldTarget7); err != nil {
-				return err
-			}
-		}
-	}
-	var8 := (m.Width == int32(0))
-	if !var8 {
-		keyTarget9, fieldTarget10, err := fieldsTarget1.StartField("Width")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget10.FromInt(int64(m.Width), vdl.Int32Type); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget9, fieldTarget10); err != nil {
-				return err
-			}
-		}
-	}
-	var11 := (m.Height == int32(0))
-	if !var11 {
-		keyTarget12, fieldTarget13, err := fieldsTarget1.StartField("Height")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget13.FromInt(int64(m.Height), vdl.Int32Type); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget12, fieldTarget13); err != nil {
-				return err
-			}
-		}
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m *Rect) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m *Rect) IsZero() bool {
-
-	var1 := (*m == Rect{})
-	return var1
-}
-
-type MultiVersionStruct struct {
-	FInt32  int32
-	FRect   Rect
-	FString string
-	FArray  []int8
-	FBool   bool
-	FInt16  int16
-}
-
-func (MultiVersionStruct) __VDLReflect(struct {
-	Name string `vdl:"src/v.io/x/mojo/transcoder/testtypes.MultiVersionStruct"`
-}) {
-}
-
-func (m *MultiVersionStruct) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	if __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_MultiVersionStruct == nil || __VDLTypetesttypes_test6 == nil {
-		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
-	}
-	fieldsTarget1, err := t.StartFields(tt)
-	if err != nil {
-		return err
-	}
-
-	var2 := (m.FInt32 == int32(0))
-	if !var2 {
-		keyTarget3, fieldTarget4, err := fieldsTarget1.StartField("FInt32")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget4.FromInt(int64(m.FInt32), vdl.Int32Type); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget3, fieldTarget4); err != nil {
-				return err
-			}
-		}
-	}
-	var5 := m.FRect.IsZero()
-	if !var5 {
-		keyTarget6, fieldTarget7, err := fieldsTarget1.StartField("FRect")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-
-			if err := m.FRect.FillVDLTarget(fieldTarget7, __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_Rect); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget6, fieldTarget7); err != nil {
-				return err
-			}
-		}
-	}
-	var8 := (m.FString == "")
-	if !var8 {
-		keyTarget9, fieldTarget10, err := fieldsTarget1.StartField("FString")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget10.FromString(string(m.FString), vdl.StringType); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget9, fieldTarget10); err != nil {
-				return err
-			}
-		}
-	}
-	var var11 bool
-	if len(m.FArray) == 0 {
-		var11 = true
-	}
-	if !var11 {
-		keyTarget12, fieldTarget13, err := fieldsTarget1.StartField("FArray")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-
-			listTarget14, err := fieldTarget13.StartList(__VDLTypetesttypes_test2, len(m.FArray))
-			if err != nil {
-				return err
-			}
-			for i, elem16 := range m.FArray {
-				elemTarget15, err := listTarget14.StartElem(i)
-				if err != nil {
-					return err
-				}
-				if err := elemTarget15.FromInt(int64(elem16), vdl.Int8Type); err != nil {
-					return err
-				}
-				if err := listTarget14.FinishElem(elemTarget15); err != nil {
-					return err
-				}
-			}
-			if err := fieldTarget13.FinishList(listTarget14); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget12, fieldTarget13); err != nil {
-				return err
-			}
-		}
-	}
-	var17 := (m.FBool == false)
-	if !var17 {
-		keyTarget18, fieldTarget19, err := fieldsTarget1.StartField("FBool")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget19.FromBool(bool(m.FBool), vdl.BoolType); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget18, fieldTarget19); err != nil {
-				return err
-			}
-		}
-	}
-	var20 := (m.FInt16 == int16(0))
-	if !var20 {
-		keyTarget21, fieldTarget22, err := fieldsTarget1.StartField("FInt16")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget22.FromInt(int64(m.FInt16), vdl.Int16Type); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget21, fieldTarget22); err != nil {
-				return err
-			}
-		}
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m *MultiVersionStruct) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m *MultiVersionStruct) IsZero() bool {
-
-	var1 := true
-	var2 := (m.FInt32 == int32(0))
-	var1 = var1 && var2
-	var3 := m.FRect.IsZero()
-	var1 = var1 && var3
-	var4 := (m.FString == "")
-	var1 = var1 && var4
-	var var5 bool
-	if len(m.FArray) == 0 {
-		var5 = true
-	}
-	var1 = var1 && var5
-	var6 := (m.FBool == false)
-	var1 = var1 && var6
-	var7 := (m.FInt16 == int16(0))
-	var1 = var1 && var7
-	return var1
-}
-
-type MultiVersionStructV3 struct {
-	FInt32  int32
-	FRect   Rect
-	FString string
-}
-
-func (MultiVersionStructV3) __VDLReflect(struct {
-	Name string `vdl:"src/v.io/x/mojo/transcoder/testtypes.MultiVersionStructV3"`
-}) {
-}
-
-func (m *MultiVersionStructV3) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
-
-	if __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_MultiVersionStructV3 == nil || __VDLTypetesttypes_test7 == nil {
-		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
-	}
-	fieldsTarget1, err := t.StartFields(tt)
-	if err != nil {
-		return err
-	}
-
-	var2 := (m.FInt32 == int32(0))
-	if !var2 {
-		keyTarget3, fieldTarget4, err := fieldsTarget1.StartField("FInt32")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget4.FromInt(int64(m.FInt32), vdl.Int32Type); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget3, fieldTarget4); err != nil {
-				return err
-			}
-		}
-	}
-	var5 := m.FRect.IsZero()
-	if !var5 {
-		keyTarget6, fieldTarget7, err := fieldsTarget1.StartField("FRect")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-
-			if err := m.FRect.FillVDLTarget(fieldTarget7, __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_Rect); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget6, fieldTarget7); err != nil {
-				return err
-			}
-		}
-	}
-	var8 := (m.FString == "")
-	if !var8 {
-		keyTarget9, fieldTarget10, err := fieldsTarget1.StartField("FString")
-		if err != vdl.ErrFieldNoExist && err != nil {
-			return err
-		}
-		if err != vdl.ErrFieldNoExist {
-			if err := fieldTarget10.FromString(string(m.FString), vdl.StringType); err != nil {
-				return err
-			}
-			if err := fieldsTarget1.FinishField(keyTarget9, fieldTarget10); err != nil {
-				return err
-			}
-		}
-	}
-	if err := t.FinishFields(fieldsTarget1); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (m *MultiVersionStructV3) MakeVDLTarget() vdl.Target {
-	return nil
-}
-
-func (m *MultiVersionStructV3) IsZero() bool {
-
-	var1 := (*m == MultiVersionStructV3{})
-	return var1
-}
-
-func init() {
-	vdl.Register((*AnEnum)(nil))
-	vdl.Register((*PodUnion)(nil))
-	vdl.Register((*PodUnionWrapper)(nil))
-	vdl.Register((*DummyStruct)(nil))
-	vdl.Register((*ObjectUnion)(nil))
-	vdl.Register((*ObjectUnionWrapper)(nil))
-	vdl.Register((*Rect)(nil))
-	vdl.Register((*MultiVersionStruct)(nil))
-	vdl.Register((*MultiVersionStructV3)(nil))
-}
-
-var __VDLTypetesttypes_test1 *vdl.Type = vdl.TypeOf((*DummyStruct)(nil))
-var __VDLTypetesttypes_test6 *vdl.Type = vdl.TypeOf((*MultiVersionStruct)(nil))
-var __VDLTypetesttypes_test7 *vdl.Type = vdl.TypeOf((*MultiVersionStructV3)(nil))
-var __VDLTypetesttypes_test4 *vdl.Type = vdl.TypeOf((*ObjectUnionWrapper)(nil))
-var __VDLTypetesttypes_test0 *vdl.Type = vdl.TypeOf((*PodUnionWrapper)(nil))
-var __VDLTypetesttypes_test5 *vdl.Type = vdl.TypeOf((*Rect)(nil))
-var __VDLTypetesttypes_test2 *vdl.Type = vdl.TypeOf([]int8(nil))
-var __VDLTypetesttypes_test3 *vdl.Type = vdl.TypeOf(map[string]int8(nil))
-var __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_AnEnum *vdl.Type = vdl.TypeOf(AnEnumFirst)
-var __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_DummyStruct *vdl.Type = vdl.TypeOf(DummyStruct{})
-var __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_MultiVersionStruct *vdl.Type = vdl.TypeOf(MultiVersionStruct{})
-var __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_MultiVersionStructV3 *vdl.Type = vdl.TypeOf(MultiVersionStructV3{})
-var __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_ObjectUnion *vdl.Type = vdl.TypeOf(ObjectUnion(ObjectUnionFInt8{}))
-var __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_ObjectUnionWrapper *vdl.Type = vdl.TypeOf(ObjectUnionWrapper{
-	ObjectUnion: ObjectUnionFInt8{},
-})
-var __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnion *vdl.Type = vdl.TypeOf(PodUnion(PodUnionFInt8{}))
-var __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_PodUnionWrapper *vdl.Type = vdl.TypeOf(PodUnionWrapper{
-	PodUnion: PodUnionFInt8{},
-})
-var __VDLType_testtypes_test_src_v_io_x_mojo_transcoder_testtypes_Rect *vdl.Type = vdl.TypeOf(Rect{})
-
-func __VDLEnsureNativeBuilt_testtypes_test() {
-}
