// 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"
	"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
	}
	var4 := (m.Street == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("Street"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Street")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			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
			}
		}
	}
	var7 := (m.City == "")
	if var7 {
		if err := fieldsTarget1.ZeroField("City"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("City")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromString(string(m.City), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var10 := (m.State == "")
	if var10 {
		if err := fieldsTarget1.ZeroField("State"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("State")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget9.FromString(string(m.State), tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
				return err
			}
		}
	}
	var13 := (m.Zip == "")
	if var13 {
		if err := fieldsTarget1.ZeroField("Zip"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget11, fieldTarget12, err := fieldsTarget1.StartField("Zip")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget12.FromString(string(m.Zip), tt.NonOptional().Field(3).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget11, fieldTarget12); 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) ZeroField(name string) error {
	switch name {
	case "Street":
		t.Value.Street = ""
		return nil
	case "City":
		t.Value.City = ""
		return nil
	case "State":
		t.Value.State = ""
		return nil
	case "Zip":
		t.Value.Zip = ""
		return nil
	default:
		return fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/internal.AddressInfo", name)
	}
}
func (t *AddressInfoTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x AddressInfo) VDLIsZero() bool {
	return x == AddressInfo{}
}

func (x AddressInfo) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*AddressInfo)(nil)).Elem()); err != nil {
		return err
	}
	if x.Street != "" {
		if err := enc.NextField("Street"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Street); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.City != "" {
		if err := enc.NextField("City"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.City); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.State != "" {
		if err := enc.NextField("State"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.State); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.Zip != "" {
		if err := enc.NextField("Zip"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Zip); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *AddressInfo) VDLRead(dec vdl.Decoder) error {
	*x = AddressInfo{}
	if err := dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Street":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Street, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "City":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.City, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "State":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.State, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Zip":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Zip, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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 CreditAgency", src)
	}

	return nil
}

func (x CreditAgency) VDLIsZero() bool {
	return x == CreditAgencyEquifax
}

func (x CreditAgency) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*CreditAgency)(nil))); err != nil {
		return err
	}
	if err := enc.EncodeString(x.String()); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *CreditAgency) VDLRead(dec vdl.Decoder) error {
	if err := dec.StartValue(); err != nil {
		return err
	}
	enum, err := dec.DecodeString()
	if err != nil {
		return err
	}
	if err := x.Set(enum); err != nil {
		return err
	}
	return dec.FinishValue()
}

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 ExperianRating", src)
	}

	return nil
}

func (x ExperianRating) VDLIsZero() bool {
	return x == ExperianRatingGood
}

func (x ExperianRating) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*ExperianRating)(nil))); err != nil {
		return err
	}
	if err := enc.EncodeString(x.String()); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *ExperianRating) VDLRead(dec vdl.Decoder) error {
	if err := dec.StartValue(); err != nil {
		return err
	}
	enum, err := dec.DecodeString()
	if err != nil {
		return err
	}
	if err := x.Set(enum); err != nil {
		return err
	}
	return dec.FinishValue()
}

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
	}
	var4 := (m.Rating == byte(0))
	if var4 {
		if err := fieldsTarget1.ZeroField("Rating"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Rating")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			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) ZeroField(name string) error {
	switch name {
	case "Rating":
		t.Value.Rating = byte(0)
		return nil
	default:
		return fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/internal.EquifaxCreditReport", name)
	}
}
func (t *EquifaxCreditReportTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x EquifaxCreditReport) VDLIsZero() bool {
	return x == EquifaxCreditReport{}
}

func (x EquifaxCreditReport) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*EquifaxCreditReport)(nil)).Elem()); err != nil {
		return err
	}
	if x.Rating != 0 {
		if err := enc.NextField("Rating"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.ByteType); err != nil {
			return err
		}
		if err := enc.EncodeUint(uint64(x.Rating)); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *EquifaxCreditReport) VDLRead(dec vdl.Decoder) error {
	*x = EquifaxCreditReport{}
	if err := dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Rating":
			if err := dec.StartValue(); err != nil {
				return err
			}
			tmp, err := dec.DecodeUint(8)
			if err != nil {
				return err
			}
			x.Rating = byte(tmp)
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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
	}
	var4 := (m.Rating == ExperianRatingGood)
	if var4 {
		if err := fieldsTarget1.ZeroField("Rating"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Rating")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			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) ZeroField(name string) error {
	switch name {
	case "Rating":
		t.Value.Rating = ExperianRatingGood
		return nil
	default:
		return fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/internal.ExperianCreditReport", name)
	}
}
func (t *ExperianCreditReportTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x ExperianCreditReport) VDLIsZero() bool {
	return x == ExperianCreditReport{}
}

func (x ExperianCreditReport) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*ExperianCreditReport)(nil)).Elem()); err != nil {
		return err
	}
	if x.Rating != ExperianRatingGood {
		if err := enc.NextField("Rating"); err != nil {
			return err
		}
		if err := x.Rating.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *ExperianCreditReport) VDLRead(dec vdl.Decoder) error {
	*x = ExperianCreditReport{}
	if err := dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Rating":
			if err := x.Rating.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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
	}
	var4 := (m.Rating == int16(0))
	if var4 {
		if err := fieldsTarget1.ZeroField("Rating"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Rating")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			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) ZeroField(name string) error {
	switch name {
	case "Rating":
		t.Value.Rating = int16(0)
		return nil
	default:
		return fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/internal.TransUnionCreditReport", name)
	}
}
func (t *TransUnionCreditReportTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x TransUnionCreditReport) VDLIsZero() bool {
	return x == TransUnionCreditReport{}
}

func (x TransUnionCreditReport) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*TransUnionCreditReport)(nil)).Elem()); err != nil {
		return err
	}
	if x.Rating != 0 {
		if err := enc.NextField("Rating"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.Int16Type); err != nil {
			return err
		}
		if err := enc.EncodeInt(int64(x.Rating)); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *TransUnionCreditReport) VDLRead(dec vdl.Decoder) error {
	*x = TransUnionCreditReport{}
	if err := dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Rating":
			if err := dec.StartValue(); err != nil {
				return err
			}
			tmp, err := dec.DecodeInt(16)
			if err != nil {
				return err
			}
			x.Rating = int16(tmp)
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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
		VDLIsZero() bool
		VDLWrite(vdl.Encoder) 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
		UnionTargetFactory agencyReportTargetFactory
		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 AgencyReportTarget struct {
	Value     *AgencyReport
	fieldName string

	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *AgencyReportTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
	if ttWant := vdl.TypeOf((*AgencyReport)(nil)); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}

	return t, nil
}
func (t *AgencyReportTarget) StartField(name string) (key, field vdl.Target, _ error) {
	t.fieldName = name
	switch name {
	case "EquifaxReport":
		val := EquifaxCreditReport{}
		return nil, &EquifaxCreditReportTarget{Value: &val}, nil
	case "ExperianReport":
		val := ExperianCreditReport{}
		return nil, &ExperianCreditReportTarget{Value: &val}, nil
	case "TransUnionReport":
		val := TransUnionCreditReport{}
		return nil, &TransUnionCreditReportTarget{Value: &val}, nil
	default:
		return nil, nil, fmt.Errorf("field %s not in union src/v.io/x/mojo/transcoder/internal.AgencyReport", name)
	}
}
func (t *AgencyReportTarget) FinishField(_, fieldTarget vdl.Target) error {
	switch t.fieldName {
	case "EquifaxReport":
		*t.Value = AgencyReportEquifaxReport{*(fieldTarget.(*EquifaxCreditReportTarget)).Value}
	case "ExperianReport":
		*t.Value = AgencyReportExperianReport{*(fieldTarget.(*ExperianCreditReportTarget)).Value}
	case "TransUnionReport":
		*t.Value = AgencyReportTransUnionReport{*(fieldTarget.(*TransUnionCreditReportTarget)).Value}
	}
	return nil
}
func (t *AgencyReportTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

type agencyReportTargetFactory struct{}

func (t agencyReportTargetFactory) VDLMakeUnionTarget(union interface{}) (vdl.Target, error) {
	if typedUnion, ok := union.(*AgencyReport); ok {
		return &AgencyReportTarget{Value: typedUnion}, nil
	}
	return nil, fmt.Errorf("got %T, want *AgencyReport", union)
}

func (x AgencyReportEquifaxReport) VDLIsZero() bool {
	return x.Value == EquifaxCreditReport{}
}

func (x AgencyReportExperianReport) VDLIsZero() bool {
	return false
}

func (x AgencyReportTransUnionReport) VDLIsZero() bool {
	return false
}

func (x AgencyReportEquifaxReport) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*AgencyReport)(nil))); err != nil {
		return err
	}
	if err := enc.NextField("EquifaxReport"); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x AgencyReportExperianReport) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*AgencyReport)(nil))); err != nil {
		return err
	}
	if err := enc.NextField("ExperianReport"); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x AgencyReportTransUnionReport) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*AgencyReport)(nil))); err != nil {
		return err
	}
	if err := enc.NextField("TransUnionReport"); err != nil {
		return err
	}
	if err := x.Value.VDLWrite(enc); err != nil {
		return err
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func VDLReadAgencyReport(dec vdl.Decoder, x *AgencyReport) error {
	if err := dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(x), dec.Type()) {
		return fmt.Errorf("incompatible union %T, from %v", x, dec.Type())
	}
	f, err := dec.NextField()
	if err != nil {
		return err
	}
	switch f {
	case "EquifaxReport":
		var field AgencyReportEquifaxReport
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case "ExperianReport":
		var field AgencyReportExperianReport
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case "TransUnionReport":
		var field AgencyReportTransUnionReport
		if err := field.Value.VDLRead(dec); err != nil {
			return err
		}
		*x = field
	case "":
		return fmt.Errorf("missing field in union %T, from %v", x, dec.Type())
	default:
		return fmt.Errorf("field %q not in union %T, from %v", f, x, dec.Type())
	}
	switch f, err := dec.NextField(); {
	case err != nil:
		return err
	case f != "":
		return fmt.Errorf("extra field %q in union %T, from %v", f, x, dec.Type())
	}
	return dec.FinishValue()
}

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
	}
	var4 := (m.Agency == CreditAgencyEquifax)
	if var4 {
		if err := fieldsTarget1.ZeroField("Agency"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Agency")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			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
			}
		}
	}
	var var7 bool
	if field, ok := m.Report.(AgencyReportEquifaxReport); ok {

		var8 := (field.Value == EquifaxCreditReport{})
		var7 = var8
	}
	if var7 {
		if err := fieldsTarget1.ZeroField("Report"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Report")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			unionValue9 := m.Report
			if unionValue9 == nil {
				unionValue9 = AgencyReportEquifaxReport{}
			}
			if err := unionValue9.FillVDLTarget(fieldTarget6, tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); 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
	reportTarget AgencyReportTarget
	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":
		t.reportTarget.Value = &t.Value.Report
		target, err := &t.reportTarget, error(nil)
		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) ZeroField(name string) error {
	switch name {
	case "Agency":
		t.Value.Agency = CreditAgencyEquifax
		return nil
	case "Report":
		t.Value.Report = AgencyReport(AgencyReportEquifaxReport{})
		return nil
	default:
		return fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/internal.CreditReport", name)
	}
}
func (t *CreditReportTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x CreditReport) VDLIsZero() bool {
	if x.Agency != CreditAgencyEquifax {
		return false
	}
	if x.Report != nil && !x.Report.VDLIsZero() {
		return false
	}
	return true
}

func (x CreditReport) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*CreditReport)(nil)).Elem()); err != nil {
		return err
	}
	if x.Agency != CreditAgencyEquifax {
		if err := enc.NextField("Agency"); err != nil {
			return err
		}
		if err := x.Agency.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Report != nil && !x.Report.VDLIsZero() {
		if err := enc.NextField("Report"); err != nil {
			return err
		}
		if err := x.Report.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *CreditReport) VDLRead(dec vdl.Decoder) error {
	*x = CreditReport{
		Report: AgencyReportEquifaxReport{},
	}
	if err := dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Agency":
			if err := x.Agency.VDLRead(dec); err != nil {
				return err
			}
		case "Report":
			if err := VDLReadAgencyReport(dec, &x.Report); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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
	}
	var4 := (m.Name == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("Name"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Name")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			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
			}
		}
	}
	var7 := (m.Id == int64(0))
	if var7 {
		if err := fieldsTarget1.ZeroField("Id"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Id")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromInt(int64(m.Id), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var10 := (m.Active == false)
	if var10 {
		if err := fieldsTarget1.ZeroField("Active"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("Active")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget9.FromBool(bool(m.Active), tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
				return err
			}
		}
	}
	var13 := (m.Address == AddressInfo{})
	if var13 {
		if err := fieldsTarget1.ZeroField("Address"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget11, fieldTarget12, err := fieldsTarget1.StartField("Address")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Address.FillVDLTarget(fieldTarget12, tt.NonOptional().Field(3).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget11, fieldTarget12); err != nil {
				return err
			}
		}
	}
	var16 := (m.Credit == CreditReport{
		Report: AgencyReportEquifaxReport{},
	})
	if var16 {
		if err := fieldsTarget1.ZeroField("Credit"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget14, fieldTarget15, err := fieldsTarget1.StartField("Credit")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Credit.FillVDLTarget(fieldTarget15, tt.NonOptional().Field(4).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget14, fieldTarget15); 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) ZeroField(name string) error {
	switch name {
	case "Name":
		t.Value.Name = ""
		return nil
	case "Id":
		t.Value.Id = int64(0)
		return nil
	case "Active":
		t.Value.Active = false
		return nil
	case "Address":
		t.Value.Address = AddressInfo{}
		return nil
	case "Credit":
		t.Value.Credit = CreditReport{
			Report: AgencyReportEquifaxReport{},
		}
		return nil
	default:
		return fmt.Errorf("field %s not in struct src/v.io/x/mojo/transcoder/internal.Customer", name)
	}
}
func (t *CustomerTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x Customer) VDLIsZero() bool {
	if x.Name != "" {
		return false
	}
	if x.Id != 0 {
		return false
	}
	if x.Active {
		return false
	}
	if x.Address != (AddressInfo{}) {
		return false
	}
	if !x.Credit.VDLIsZero() {
		return false
	}
	return true
}

func (x Customer) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*Customer)(nil)).Elem()); err != nil {
		return err
	}
	if x.Name != "" {
		if err := enc.NextField("Name"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Name); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.Id != 0 {
		if err := enc.NextField("Id"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.Int64Type); err != nil {
			return err
		}
		if err := enc.EncodeInt(x.Id); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.Active {
		if err := enc.NextField("Active"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.BoolType); err != nil {
			return err
		}
		if err := enc.EncodeBool(x.Active); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.Address != (AddressInfo{}) {
		if err := enc.NextField("Address"); err != nil {
			return err
		}
		if err := x.Address.VDLWrite(enc); err != nil {
			return err
		}
	}
	if !x.Credit.VDLIsZero() {
		if err := enc.NextField("Credit"); err != nil {
			return err
		}
		if err := x.Credit.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *Customer) VDLRead(dec vdl.Decoder) error {
	*x = Customer{
		Credit: CreditReport{
			Report: AgencyReportEquifaxReport{},
		},
	}
	if err := dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Name":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Name, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Id":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Id, err = dec.DecodeInt(64); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Active":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Active, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Address":
			if err := x.Address.VDLRead(dec); err != nil {
				return err
			}
		case "Credit":
			if err := x.Credit.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

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{}{}
	}
	__VDLInitCalled = true

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