// 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, vdl.ErrFieldNoExist
	}
}
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 vdl.ErrFieldNoExist
	}
}
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, vdl.ErrFieldNoExist
	}
}
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 vdl.ErrFieldNoExist
	}
}
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, vdl.ErrFieldNoExist
	}
}
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 vdl.ErrFieldNoExist
	}
}
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, vdl.ErrFieldNoExist
	}
}
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 vdl.ErrFieldNoExist
	}
}
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, vdl.ErrFieldNoExist
	}
}
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 vdl.ErrFieldNoExist
	}
}
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, vdl.ErrFieldNoExist
	}
}
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 vdl.ErrFieldNoExist
	}
}
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{}{}
}
