// 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  __VDLTarget1_list
	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 __VDLTarget1_list struct {
	Value      *[]int8
	elemTarget vdl.Int8Target
	vdl.TargetBase
	vdl.ListTargetBase
}

func (t *__VDLTarget1_list) 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 *__VDLTarget1_list) StartElem(index int) (elem vdl.Target, _ error) {
	t.elemTarget.Value = &(*t.Value)[index]
	target, err := &t.elemTarget, error(nil)
	return target, err
}
func (t *__VDLTarget1_list) FinishElem(elem vdl.Target) error {
	return nil
}
func (t *__VDLTarget1_list) 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
}

// Create zero values for each type.
var (
	__VDLZeroAnEnum          = AnEnumFirst
	__VDLZeroPodUnion        = PodUnion(PodUnionFInt8{})
	__VDLZeroPodUnionWrapper = PodUnionWrapper{
		PodUnion: PodUnionFInt8{},
	}
	__VDLZeroDummyStruct        = DummyStruct{}
	__VDLZeroObjectUnion        = ObjectUnion(ObjectUnionFInt8{})
	__VDLZeroObjectUnionWrapper = ObjectUnionWrapper{
		ObjectUnion: ObjectUnionFInt8{},
	}
	__VDLZeroRect                 = Rect{}
	__VDLZeroMultiVersionStruct   = MultiVersionStruct{}
	__VDLZeroMultiVersionStructV3 = MultiVersionStructV3{}
)

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{}{}
}
