// 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: vdltool

// Package vdltool defines types used by the vdl tool itself, including the
// format of vdl.config files.
package vdltool

import (
	"fmt"
	"reflect"
	"v.io/v23/vdl"
)

var _ = __VDLInit() // Must be first; see __VDLInit comments for details.

//////////////////////////////////////////////////
// Type definitions

// GenLanguage enumerates the known code generation languages.
type GenLanguage int

const (
	GenLanguageGo GenLanguage = iota
	GenLanguageJava
	GenLanguageJavascript
	GenLanguageSwift
)

// GenLanguageAll holds all labels for GenLanguage.
var GenLanguageAll = [...]GenLanguage{GenLanguageGo, GenLanguageJava, GenLanguageJavascript, GenLanguageSwift}

// GenLanguageFromString creates a GenLanguage from a string label.
func GenLanguageFromString(label string) (x GenLanguage, err error) {
	err = x.Set(label)
	return
}

// Set assigns label to x.
func (x *GenLanguage) Set(label string) error {
	switch label {
	case "Go", "go":
		*x = GenLanguageGo
		return nil
	case "Java", "java":
		*x = GenLanguageJava
		return nil
	case "Javascript", "javascript":
		*x = GenLanguageJavascript
		return nil
	case "Swift", "swift":
		*x = GenLanguageSwift
		return nil
	}
	*x = -1
	return fmt.Errorf("unknown label %q in vdltool.GenLanguage", label)
}

// String returns the string label of x.
func (x GenLanguage) String() string {
	switch x {
	case GenLanguageGo:
		return "Go"
	case GenLanguageJava:
		return "Java"
	case GenLanguageJavascript:
		return "Javascript"
	case GenLanguageSwift:
		return "Swift"
	}
	return ""
}

func (GenLanguage) __VDLReflect(struct {
	Name string `vdl:"vdltool.GenLanguage"`
	Enum struct{ Go, Java, Javascript, Swift string }
}) {
}

func (m *GenLanguage) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	if err := t.FromEnumLabel((*m).String(), tt); err != nil {
		return err
	}
	return nil
}

func (m *GenLanguage) MakeVDLTarget() vdl.Target {
	return nil
}

type GenLanguageTarget struct {
	Value *GenLanguage
	vdl.TargetBase
}

func (t *GenLanguageTarget) FromEnumLabel(src string, tt *vdl.Type) error {

	if ttWant := vdl.TypeOf((*GenLanguage)(nil)); !vdl.Compatible(tt, ttWant) {
		return fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	switch src {
	case "Go":
		*t.Value = 0
	case "Java":
		*t.Value = 1
	case "Javascript":
		*t.Value = 2
	case "Swift":
		*t.Value = 3
	default:
		return fmt.Errorf("label %s not in enum GenLanguage", src)
	}

	return nil
}

func (x GenLanguage) VDLIsZero() bool {
	return x == GenLanguageGo
}

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

func (x *GenLanguage) 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()
}

// GoKind describes the kind of Go type.
type GoKind int

const (
	GoKindStruct GoKind = iota
	GoKindBool
	GoKindNumber
	GoKindString
	GoKindArray
	GoKindSlice
	GoKindMap
	GoKindPointer
)

// GoKindAll holds all labels for GoKind.
var GoKindAll = [...]GoKind{GoKindStruct, GoKindBool, GoKindNumber, GoKindString, GoKindArray, GoKindSlice, GoKindMap, GoKindPointer}

// GoKindFromString creates a GoKind from a string label.
func GoKindFromString(label string) (x GoKind, err error) {
	err = x.Set(label)
	return
}

// Set assigns label to x.
func (x *GoKind) Set(label string) error {
	switch label {
	case "Struct", "struct":
		*x = GoKindStruct
		return nil
	case "Bool", "bool":
		*x = GoKindBool
		return nil
	case "Number", "number":
		*x = GoKindNumber
		return nil
	case "String", "string":
		*x = GoKindString
		return nil
	case "Array", "array":
		*x = GoKindArray
		return nil
	case "Slice", "slice":
		*x = GoKindSlice
		return nil
	case "Map", "map":
		*x = GoKindMap
		return nil
	case "Pointer", "pointer":
		*x = GoKindPointer
		return nil
	}
	*x = -1
	return fmt.Errorf("unknown label %q in vdltool.GoKind", label)
}

// String returns the string label of x.
func (x GoKind) String() string {
	switch x {
	case GoKindStruct:
		return "Struct"
	case GoKindBool:
		return "Bool"
	case GoKindNumber:
		return "Number"
	case GoKindString:
		return "String"
	case GoKindArray:
		return "Array"
	case GoKindSlice:
		return "Slice"
	case GoKindMap:
		return "Map"
	case GoKindPointer:
		return "Pointer"
	}
	return ""
}

func (GoKind) __VDLReflect(struct {
	Name string `vdl:"vdltool.GoKind"`
	Enum struct{ Struct, Bool, Number, String, Array, Slice, Map, Pointer string }
}) {
}

func (m *GoKind) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	if err := t.FromEnumLabel((*m).String(), tt); err != nil {
		return err
	}
	return nil
}

func (m *GoKind) MakeVDLTarget() vdl.Target {
	return nil
}

type GoKindTarget struct {
	Value *GoKind
	vdl.TargetBase
}

func (t *GoKindTarget) FromEnumLabel(src string, tt *vdl.Type) error {

	if ttWant := vdl.TypeOf((*GoKind)(nil)); !vdl.Compatible(tt, ttWant) {
		return fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	switch src {
	case "Struct":
		*t.Value = 0
	case "Bool":
		*t.Value = 1
	case "Number":
		*t.Value = 2
	case "String":
		*t.Value = 3
	case "Array":
		*t.Value = 4
	case "Slice":
		*t.Value = 5
	case "Map":
		*t.Value = 6
	case "Pointer":
		*t.Value = 7
	default:
		return fmt.Errorf("label %s not in enum GoKind", src)
	}

	return nil
}

func (x GoKind) VDLIsZero() bool {
	return x == GoKindStruct
}

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

func (x *GoKind) 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()
}

// GoImport describes Go import information.
type GoImport struct {
	// Path is the package path that uniquely identifies the imported package.
	Path string
	// Name is the name of the package identified by Path.  Due to Go conventions,
	// it is typically just the basename of Path, but may be set to something
	// different if the imported package doesn't follow Go conventions.
	Name string
}

func (GoImport) __VDLReflect(struct {
	Name string `vdl:"vdltool.GoImport"`
}) {
}

func (m *GoImport) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Path == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("Path"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Path")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.Path), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.Name == "")
	if var7 {
		if err := fieldsTarget1.ZeroField("Name"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Name")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromString(string(m.Name), 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 *GoImport) MakeVDLTarget() vdl.Target {
	return nil
}

type GoImportTarget struct {
	Value *GoImport

	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *GoImportTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*GoImport)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *GoImportTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Path":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Path))
		return nil, target, err
	case "Name":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Name))
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *GoImportTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *GoImportTarget) ZeroField(name string) error {
	switch name {
	case "Path":
		t.Value.Path = ""
		return nil
	case "Name":
		t.Value.Name = ""
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *GoImportTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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

func (x GoImport) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*GoImport)(nil)).Elem()); err != nil {
		return err
	}
	if x.Path != "" {
		if err := enc.NextField("Path"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Path); err != nil {
			return err
		}
		if err := enc.FinishValue(); 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 err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *GoImport) VDLRead(dec vdl.Decoder) error {
	*x = GoImport{}
	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 "Path":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Path, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		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
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// GoZeroMode describes the relationship between the Go zero value of the native
// type, and the VDL zero value.
type GoZeroMode int

const (
	GoZeroModeUnknown GoZeroMode = iota
	GoZeroModeCanonical
	GoZeroModeUnique
)

// GoZeroModeAll holds all labels for GoZeroMode.
var GoZeroModeAll = [...]GoZeroMode{GoZeroModeUnknown, GoZeroModeCanonical, GoZeroModeUnique}

// GoZeroModeFromString creates a GoZeroMode from a string label.
func GoZeroModeFromString(label string) (x GoZeroMode, err error) {
	err = x.Set(label)
	return
}

// Set assigns label to x.
func (x *GoZeroMode) Set(label string) error {
	switch label {
	case "Unknown", "unknown":
		*x = GoZeroModeUnknown
		return nil
	case "Canonical", "canonical":
		*x = GoZeroModeCanonical
		return nil
	case "Unique", "unique":
		*x = GoZeroModeUnique
		return nil
	}
	*x = -1
	return fmt.Errorf("unknown label %q in vdltool.GoZeroMode", label)
}

// String returns the string label of x.
func (x GoZeroMode) String() string {
	switch x {
	case GoZeroModeUnknown:
		return "Unknown"
	case GoZeroModeCanonical:
		return "Canonical"
	case GoZeroModeUnique:
		return "Unique"
	}
	return ""
}

func (GoZeroMode) __VDLReflect(struct {
	Name string `vdl:"vdltool.GoZeroMode"`
	Enum struct{ Unknown, Canonical, Unique string }
}) {
}

func (m *GoZeroMode) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	if err := t.FromEnumLabel((*m).String(), tt); err != nil {
		return err
	}
	return nil
}

func (m *GoZeroMode) MakeVDLTarget() vdl.Target {
	return nil
}

type GoZeroModeTarget struct {
	Value *GoZeroMode
	vdl.TargetBase
}

func (t *GoZeroModeTarget) FromEnumLabel(src string, tt *vdl.Type) error {

	if ttWant := vdl.TypeOf((*GoZeroMode)(nil)); !vdl.Compatible(tt, ttWant) {
		return fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	switch src {
	case "Unknown":
		*t.Value = 0
	case "Canonical":
		*t.Value = 1
	case "Unique":
		*t.Value = 2
	default:
		return fmt.Errorf("label %s not in enum GoZeroMode", src)
	}

	return nil
}

func (x GoZeroMode) VDLIsZero() bool {
	return x == GoZeroModeUnknown
}

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

func (x *GoZeroMode) 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()
}

// GoZero describes Go zero value behavior.
//
// REQUIRED: Either Mode == Unique or IsZero is set.  We will not perform
// native/wire conversions to check zero values.
type GoZero struct {
	Mode GoZeroMode
	// IsZero specifies a field, method or function that returns true iff the
	// native value represents the VDL zero value.
	//
	// If IsZero starts with a dot (.), it is assumed to be a field or method.
	// The field type or method return type must be bool.  Generated code will
	// apply the IsZero string verbatim to expressions of the native type.
	//
	// If IsZero doesn't start with a dot(.), it is assumed to be a function whose
	// return type must be bool.  Generated code will call the function with all
	// occurrences of XXX replaced with an expression of the native type.
	//
	// TODO(toddw): The function form of IsZero isn't implemented, and also needs
	// another field to handle imports:
	//    IsZeroImports []GoImport
	IsZero string
}

func (GoZero) __VDLReflect(struct {
	Name string `vdl:"vdltool.GoZero"`
}) {
}

func (m *GoZero) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Mode == GoZeroModeUnknown)
	if var4 {
		if err := fieldsTarget1.ZeroField("Mode"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Mode")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Mode.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.IsZero == "")
	if var7 {
		if err := fieldsTarget1.ZeroField("IsZero"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("IsZero")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromString(string(m.IsZero), 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 *GoZero) MakeVDLTarget() vdl.Target {
	return nil
}

type GoZeroTarget struct {
	Value *GoZero

	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *GoZeroTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*GoZero)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *GoZeroTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Mode":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Mode))
		return nil, target, err
	case "IsZero":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.IsZero))
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *GoZeroTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *GoZeroTarget) ZeroField(name string) error {
	switch name {
	case "Mode":
		t.Value.Mode = GoZeroModeUnknown
		return nil
	case "IsZero":
		t.Value.IsZero = ""
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *GoZeroTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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

func (x GoZero) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*GoZero)(nil)).Elem()); err != nil {
		return err
	}
	if x.Mode != GoZeroModeUnknown {
		if err := enc.NextField("Mode"); err != nil {
			return err
		}
		if err := x.Mode.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.IsZero != "" {
		if err := enc.NextField("IsZero"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.IsZero); 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 *GoZero) VDLRead(dec vdl.Decoder) error {
	*x = GoZero{}
	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 "Mode":
			if err := x.Mode.VDLRead(dec); err != nil {
				return err
			}
		case "IsZero":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.IsZero, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// GoType describes the Go type information associated with a VDL type.
// See v.io/x/ref/lib/vdl/testdata/native for examples.
type GoType struct {
	// Kind is the kind of Type.
	Kind GoKind
	// Type is the Go type to use in generated code, instead of the VDL type.
	//
	// If the Go type requires additional imports, specify the type using the
	// standard local package name here, and also specify the import package in
	// Imports.  E.g. to specify the native type time.Duration:
	//   Kind:    Number
	//   Type:    "time.Duration",
	//   Imports: {{Path: "time", Name: "time"}},
	//   Zero:    {Mode: Unique}
	Type string
	// Imports are the Go imports required by the Type, used in generated code.
	Imports []GoImport
	// Zero specifies special behavior for zero value setting and checking.
	Zero GoZero
}

func (GoType) __VDLReflect(struct {
	Name string `vdl:"vdltool.GoType"`
}) {
}

func (m *GoType) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Kind == GoKindStruct)
	if var4 {
		if err := fieldsTarget1.ZeroField("Kind"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Kind")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Kind.FillVDLTarget(fieldTarget3, tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.Type == "")
	if var7 {
		if err := fieldsTarget1.ZeroField("Type"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Type")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromString(string(m.Type), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var var10 bool
	if len(m.Imports) == 0 {
		var10 = true
	}
	if var10 {
		if err := fieldsTarget1.ZeroField("Imports"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("Imports")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			listTarget11, err := fieldTarget9.StartList(tt.NonOptional().Field(2).Type, len(m.Imports))
			if err != nil {
				return err
			}
			for i, elem13 := range m.Imports {
				elemTarget12, err := listTarget11.StartElem(i)
				if err != nil {
					return err
				}

				if err := elem13.FillVDLTarget(elemTarget12, tt.NonOptional().Field(2).Type.Elem()); err != nil {
					return err
				}
				if err := listTarget11.FinishElem(elemTarget12); err != nil {
					return err
				}
			}
			if err := fieldTarget9.FinishList(listTarget11); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
				return err
			}
		}
	}
	var16 := (m.Zero == GoZero{})
	if var16 {
		if err := fieldsTarget1.ZeroField("Zero"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget14, fieldTarget15, err := fieldsTarget1.StartField("Zero")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Zero.FillVDLTarget(fieldTarget15, tt.NonOptional().Field(3).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 *GoType) MakeVDLTarget() vdl.Target {
	return nil
}

type GoTypeTarget struct {
	Value *GoType

	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *GoTypeTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*GoType)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *GoTypeTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Kind":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Kind))
		return nil, target, err
	case "Type":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Type))
		return nil, target, err
	case "Imports":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Imports))
		return nil, target, err
	case "Zero":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Zero))
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *GoTypeTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *GoTypeTarget) ZeroField(name string) error {
	switch name {
	case "Kind":
		t.Value.Kind = GoKindStruct
		return nil
	case "Type":
		t.Value.Type = ""
		return nil
	case "Imports":
		t.Value.Imports = []GoImport(nil)
		return nil
	case "Zero":
		t.Value.Zero = GoZero{}
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *GoTypeTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x GoType) VDLIsZero() bool {
	if x.Kind != GoKindStruct {
		return false
	}
	if x.Type != "" {
		return false
	}
	if len(x.Imports) != 0 {
		return false
	}
	if x.Zero != (GoZero{}) {
		return false
	}
	return true
}

func (x GoType) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*GoType)(nil)).Elem()); err != nil {
		return err
	}
	if x.Kind != GoKindStruct {
		if err := enc.NextField("Kind"); err != nil {
			return err
		}
		if err := x.Kind.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Type != "" {
		if err := enc.NextField("Type"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Type); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if len(x.Imports) != 0 {
		if err := enc.NextField("Imports"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Imports); err != nil {
			return err
		}
	}
	if x.Zero != (GoZero{}) {
		if err := enc.NextField("Zero"); err != nil {
			return err
		}
		if err := x.Zero.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_1(enc vdl.Encoder, x []GoImport) error {
	if err := enc.StartValue(vdl.TypeOf((*[]GoImport)(nil))); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for i := 0; i < len(x); i++ {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := x[i].VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *GoType) VDLRead(dec vdl.Decoder) error {
	*x = GoType{}
	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 "Kind":
			if err := x.Kind.VDLRead(dec); err != nil {
				return err
			}
		case "Type":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Type, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Imports":
			if err := __VDLReadAnon_list_1(dec, &x.Imports); err != nil {
				return err
			}
		case "Zero":
			if err := x.Zero.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_list_1(dec vdl.Decoder, x *[]GoImport) 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 list %T, from %v", *x, dec.Type())
	}
	switch len := dec.LenHint(); {
	case len > 0:
		*x = make([]GoImport, 0, len)
	default:
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		}
		var elem GoImport
		if err := elem.VDLRead(dec); err != nil {
			return err
		}
		*x = append(*x, elem)
	}
}

// GoConfig specifies go specific configuration.
type GoConfig struct {
	// WireToNativeTypes specifies the mapping from a VDL wire type to its Go
	// native type representation.  This is rarely used and easy to configure
	// incorrectly; usage is currently restricted to packages that are explicitly
	// whitelisted.
	//
	// WireToNativeTypes are meant for scenarios where there is an idiomatic Go
	// type used in your code, but you need a standard VDL representation for wire
	// compatibility.  E.g. the VDL time package defines Duration and Time for
	// wire compatibility, but we want the generated code to use the standard Go
	// time package.
	//
	// The key of the map is the name of the VDL type (aka WireType), which must
	// be defined in the vdl package associated with the vdl.config file.
	//
	// The code generator assumes the existence of a pair of conversion functions
	// converting between the wire and native types, and will automatically call
	// vdl.RegisterNative with these function names.
	//
	// Assuming the name of the WireType is Foo:
	//   func fooToNative(x Foo, n *Native) error
	//   func fooFromNative(x *Foo, n Native) error
	WireToNativeTypes map[string]GoType
}

func (GoConfig) __VDLReflect(struct {
	Name string `vdl:"vdltool.GoConfig"`
}) {
}

func (m *GoConfig) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var var4 bool
	if len(m.WireToNativeTypes) == 0 {
		var4 = true
	}
	if var4 {
		if err := fieldsTarget1.ZeroField("WireToNativeTypes"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("WireToNativeTypes")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			mapTarget5, err := fieldTarget3.StartMap(tt.NonOptional().Field(0).Type, len(m.WireToNativeTypes))
			if err != nil {
				return err
			}
			for key7, value9 := range m.WireToNativeTypes {
				keyTarget6, err := mapTarget5.StartKey()
				if err != nil {
					return err
				}
				if err := keyTarget6.FromString(string(key7), tt.NonOptional().Field(0).Type.Key()); err != nil {
					return err
				}
				valueTarget8, err := mapTarget5.FinishKeyStartField(keyTarget6)
				if err != nil {
					return err
				}

				if err := value9.FillVDLTarget(valueTarget8, tt.NonOptional().Field(0).Type.Elem()); err != nil {
					return err
				}
				if err := mapTarget5.FinishField(keyTarget6, valueTarget8); err != nil {
					return err
				}
			}
			if err := fieldTarget3.FinishMap(mapTarget5); 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 *GoConfig) MakeVDLTarget() vdl.Target {
	return nil
}

type GoConfigTarget struct {
	Value *GoConfig

	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *GoConfigTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*GoConfig)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *GoConfigTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "WireToNativeTypes":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.WireToNativeTypes))
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *GoConfigTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *GoConfigTarget) ZeroField(name string) error {
	switch name {
	case "WireToNativeTypes":
		t.Value.WireToNativeTypes = map[string]GoType(nil)
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *GoConfigTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x GoConfig) VDLIsZero() bool {
	if len(x.WireToNativeTypes) != 0 {
		return false
	}
	return true
}

func (x GoConfig) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*GoConfig)(nil)).Elem()); err != nil {
		return err
	}
	if len(x.WireToNativeTypes) != 0 {
		if err := enc.NextField("WireToNativeTypes"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_map_2(enc, x.WireToNativeTypes); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_map_2(enc vdl.Encoder, x map[string]GoType) error {
	if err := enc.StartValue(vdl.TypeOf((*map[string]GoType)(nil))); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for key, elem := range x {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(key); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
		if err := elem.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *GoConfig) VDLRead(dec vdl.Decoder) error {
	*x = GoConfig{}
	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 "WireToNativeTypes":
			if err := __VDLReadAnon_map_2(dec, &x.WireToNativeTypes); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_map_2(dec vdl.Decoder, x *map[string]GoType) 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 map %T, from %v", *x, dec.Type())
	}
	var tmpMap map[string]GoType
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(map[string]GoType, len)
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		}
		var key string
		{
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if key, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		}
		var elem GoType
		{
			if err := elem.VDLRead(dec); err != nil {
				return err
			}
		}
		if tmpMap == nil {
			tmpMap = make(map[string]GoType)
		}
		tmpMap[key] = elem
	}
}

// JavaConfig specifies java specific configuration.
type JavaConfig struct {
	// WireToNativeTypes specifies the mapping from a VDL wire type to its Java
	// native type representation.  This is rarely used and easy to configure
	// incorrectly; usage is currently restricted to packages that are explicitly
	// whitelisted.
	//
	// WireToNativeTypes are meant for scenarios where there is an idiomatic Java
	// type used in your code, but you need a standard VDL representation for wire
	// compatibility.  E.g. the VDL time package defines Duration and Time for
	// wire compatibility, but we want the generated code to use the org.joda.time
	// package.
	//
	// The key of the map is the name of the VDL type (aka WireType), which must
	// be defined in the vdl package associated with the vdl.config file.
	//
	// The code generator assumes that the conversion functions will be registered
	// in java vdl package.
	WireToNativeTypes map[string]string
	// WireTypeRenames specifies the mapping from a VDL wire type name to its
	// Java native type name.
	//
	// WireTypeRenames are meant for scenarios where the VDL wire name
	// conflicts in some way with the Java native names, e.g., a VDL Integer
	// type could be named VInteger for clarity.
	//
	// When combined with WireToNativeTypes, this feature allows us to attach
	// functions to VDL types.  For example, we may rename AccessList VDL type
	// into WireAccessList and then map WireAccessList to our Java native type
	// AccessList which defines functions on the VDL data.
	//
	// The key of the map is the name of the VDL wire type, which must be
	// defined in the vdl package associated with the vdl.config file.
	WireTypeRenames map[string]string
}

func (JavaConfig) __VDLReflect(struct {
	Name string `vdl:"vdltool.JavaConfig"`
}) {
}

func (m *JavaConfig) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var var4 bool
	if len(m.WireToNativeTypes) == 0 {
		var4 = true
	}
	if var4 {
		if err := fieldsTarget1.ZeroField("WireToNativeTypes"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("WireToNativeTypes")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			mapTarget5, err := fieldTarget3.StartMap(tt.NonOptional().Field(0).Type, len(m.WireToNativeTypes))
			if err != nil {
				return err
			}
			for key7, value9 := range m.WireToNativeTypes {
				keyTarget6, err := mapTarget5.StartKey()
				if err != nil {
					return err
				}
				if err := keyTarget6.FromString(string(key7), tt.NonOptional().Field(0).Type.Key()); err != nil {
					return err
				}
				valueTarget8, err := mapTarget5.FinishKeyStartField(keyTarget6)
				if err != nil {
					return err
				}
				if err := valueTarget8.FromString(string(value9), tt.NonOptional().Field(0).Type.Elem()); err != nil {
					return err
				}
				if err := mapTarget5.FinishField(keyTarget6, valueTarget8); err != nil {
					return err
				}
			}
			if err := fieldTarget3.FinishMap(mapTarget5); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var var12 bool
	if len(m.WireTypeRenames) == 0 {
		var12 = true
	}
	if var12 {
		if err := fieldsTarget1.ZeroField("WireTypeRenames"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget10, fieldTarget11, err := fieldsTarget1.StartField("WireTypeRenames")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			mapTarget13, err := fieldTarget11.StartMap(tt.NonOptional().Field(1).Type, len(m.WireTypeRenames))
			if err != nil {
				return err
			}
			for key15, value17 := range m.WireTypeRenames {
				keyTarget14, err := mapTarget13.StartKey()
				if err != nil {
					return err
				}
				if err := keyTarget14.FromString(string(key15), tt.NonOptional().Field(1).Type.Key()); err != nil {
					return err
				}
				valueTarget16, err := mapTarget13.FinishKeyStartField(keyTarget14)
				if err != nil {
					return err
				}
				if err := valueTarget16.FromString(string(value17), tt.NonOptional().Field(1).Type.Elem()); err != nil {
					return err
				}
				if err := mapTarget13.FinishField(keyTarget14, valueTarget16); err != nil {
					return err
				}
			}
			if err := fieldTarget11.FinishMap(mapTarget13); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget10, fieldTarget11); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *JavaConfig) MakeVDLTarget() vdl.Target {
	return nil
}

type JavaConfigTarget struct {
	Value *JavaConfig

	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *JavaConfigTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*JavaConfig)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *JavaConfigTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "WireToNativeTypes":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.WireToNativeTypes))
		return nil, target, err
	case "WireTypeRenames":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.WireTypeRenames))
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *JavaConfigTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *JavaConfigTarget) ZeroField(name string) error {
	switch name {
	case "WireToNativeTypes":
		t.Value.WireToNativeTypes = map[string]string(nil)
		return nil
	case "WireTypeRenames":
		t.Value.WireTypeRenames = map[string]string(nil)
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *JavaConfigTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x JavaConfig) VDLIsZero() bool {
	if len(x.WireToNativeTypes) != 0 {
		return false
	}
	if len(x.WireTypeRenames) != 0 {
		return false
	}
	return true
}

func (x JavaConfig) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*JavaConfig)(nil)).Elem()); err != nil {
		return err
	}
	if len(x.WireToNativeTypes) != 0 {
		if err := enc.NextField("WireToNativeTypes"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_map_3(enc, x.WireToNativeTypes); err != nil {
			return err
		}
	}
	if len(x.WireTypeRenames) != 0 {
		if err := enc.NextField("WireTypeRenames"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_map_3(enc, x.WireTypeRenames); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_map_3(enc vdl.Encoder, x map[string]string) error {
	if err := enc.StartValue(vdl.TypeOf((*map[string]string)(nil))); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for key, elem := range x {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(key); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.StringType); err != nil {
			return err
		}
		if err := enc.EncodeString(elem); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *JavaConfig) VDLRead(dec vdl.Decoder) error {
	*x = JavaConfig{}
	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 "WireToNativeTypes":
			if err := __VDLReadAnon_map_3(dec, &x.WireToNativeTypes); err != nil {
				return err
			}
		case "WireTypeRenames":
			if err := __VDLReadAnon_map_3(dec, &x.WireTypeRenames); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_map_3(dec vdl.Decoder, x *map[string]string) 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 map %T, from %v", *x, dec.Type())
	}
	var tmpMap map[string]string
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(map[string]string, len)
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		}
		var key string
		{
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if key, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		}
		var elem string
		{
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if elem, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		}
		if tmpMap == nil {
			tmpMap = make(map[string]string)
		}
		tmpMap[key] = elem
	}
}

// JavascriptConfig specifies javascript specific configuration.
type JavascriptConfig struct {
}

func (JavascriptConfig) __VDLReflect(struct {
	Name string `vdl:"vdltool.JavascriptConfig"`
}) {
}

func (m *JavascriptConfig) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *JavascriptConfig) MakeVDLTarget() vdl.Target {
	return nil
}

type JavascriptConfigTarget struct {
	Value *JavascriptConfig
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *JavascriptConfigTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*JavascriptConfig)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *JavascriptConfigTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *JavascriptConfigTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *JavascriptConfigTarget) ZeroField(name string) error {
	switch name {
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *JavascriptConfigTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

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

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

func (x *JavascriptConfig) VDLRead(dec vdl.Decoder) error {
	*x = JavascriptConfig{}
	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()
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// SwiftConfig specifies swift specific configuration for this package.
// Note that despite the SwiftConfig options for a given package (which should be
// very rare in practice), we still need to know the name of the swift module
// that this package relates to to properly understand import boundaries between
// projects/frameworks/modules.
//
// We do this by defining a file called "swiftmodule" that contains JUST the
// name of the Swift module at the root of your VDL packages. For example,
// if you have the VDL files for your Xcode project/target called UberForCats
// at /Users/aaron/uberforcats/vdl, then create
// /Users/aaron/uberforcats/vdl/com.uberforcats/swiftmodule and have it just contain
// "UberForCats". We then will treat any VDL files contained in that directory and
// any subdirectories as part of the UberForCats Swift module, ultimately letting
// the compiler and will automatically do the right thing if others import your package.
// If you don't do this then nobody will be able to import your VDL types in Swift,
// and you might end up with extra long class/pkg names (ComuberforcatsServicesProfit
// instead of ServicesProfit for $VDLROOT/com.uberforcats/services/profit).
//
// If you are creating multiple Swift modules for a given $VDLROOT then just place
// swiftmodule files at the logical boundaries. For eample, we do this for v.io/v23
// to be exported to the VanadiumCore framework, but everything under v.io/v23/services
// lives in the VanadiumServices framework.
type SwiftConfig struct {
	// WireToNativeTypes specifies the mapping from a VDL wire type to its Swift
	// native type representation.  This is rarely used and easy to configure
	// incorrectly; usage is currently restricted to packages that are explicitly
	// whitelisted.
	//
	// WireToNativeTypes are meant for scenarios where there is an idiomatic Swift
	// type used in your code, but you need a standard VDL representation for wire
	// compatibility.  E.g. the VDL time package defines Duration and Time for
	// wire compatibility, but we want the generated code to use NSDate or NSTimeInterval
	//
	// The key of the map is the name of the VDL type (aka WireType), which must
	// be defined in the vdl package associated with the vdl.config file.
	//
	// The code generator assumes that the conversion functions will be registered
	// in Swift vdl package.
	WireToNativeTypes map[string]string
}

func (SwiftConfig) __VDLReflect(struct {
	Name string `vdl:"vdltool.SwiftConfig"`
}) {
}

func (m *SwiftConfig) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var var4 bool
	if len(m.WireToNativeTypes) == 0 {
		var4 = true
	}
	if var4 {
		if err := fieldsTarget1.ZeroField("WireToNativeTypes"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("WireToNativeTypes")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			mapTarget5, err := fieldTarget3.StartMap(tt.NonOptional().Field(0).Type, len(m.WireToNativeTypes))
			if err != nil {
				return err
			}
			for key7, value9 := range m.WireToNativeTypes {
				keyTarget6, err := mapTarget5.StartKey()
				if err != nil {
					return err
				}
				if err := keyTarget6.FromString(string(key7), tt.NonOptional().Field(0).Type.Key()); err != nil {
					return err
				}
				valueTarget8, err := mapTarget5.FinishKeyStartField(keyTarget6)
				if err != nil {
					return err
				}
				if err := valueTarget8.FromString(string(value9), tt.NonOptional().Field(0).Type.Elem()); err != nil {
					return err
				}
				if err := mapTarget5.FinishField(keyTarget6, valueTarget8); err != nil {
					return err
				}
			}
			if err := fieldTarget3.FinishMap(mapTarget5); 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 *SwiftConfig) MakeVDLTarget() vdl.Target {
	return nil
}

type SwiftConfigTarget struct {
	Value *SwiftConfig

	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *SwiftConfigTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*SwiftConfig)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *SwiftConfigTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "WireToNativeTypes":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.WireToNativeTypes))
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *SwiftConfigTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *SwiftConfigTarget) ZeroField(name string) error {
	switch name {
	case "WireToNativeTypes":
		t.Value.WireToNativeTypes = map[string]string(nil)
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *SwiftConfigTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x SwiftConfig) VDLIsZero() bool {
	if len(x.WireToNativeTypes) != 0 {
		return false
	}
	return true
}

func (x SwiftConfig) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*SwiftConfig)(nil)).Elem()); err != nil {
		return err
	}
	if len(x.WireToNativeTypes) != 0 {
		if err := enc.NextField("WireToNativeTypes"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_map_3(enc, x.WireToNativeTypes); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *SwiftConfig) VDLRead(dec vdl.Decoder) error {
	*x = SwiftConfig{}
	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 "WireToNativeTypes":
			if err := __VDLReadAnon_map_3(dec, &x.WireToNativeTypes); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// Config specifies the configuration for the vdl tool.  This is typically
// represented in optional "vdl.config" files in each vdl source package.  Each
// vdl.config file implicitly imports this package.  E.g. you may refer to
// vdltool.Config in the "vdl.config" file without explicitly importing vdltool.
type Config struct {
	// GenLanguages restricts the set of code generation languages.  If the set is
	// empty, all supported languages are allowed to be generated.
	GenLanguages map[GenLanguage]struct{}
	// Language-specific configurations.
	Go         GoConfig
	Java       JavaConfig
	Javascript JavascriptConfig
	Swift      SwiftConfig
}

func (Config) __VDLReflect(struct {
	Name string `vdl:"vdltool.Config"`
}) {
}

func (m *Config) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var var4 bool
	if len(m.GenLanguages) == 0 {
		var4 = true
	}
	if var4 {
		if err := fieldsTarget1.ZeroField("GenLanguages"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("GenLanguages")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			setTarget5, err := fieldTarget3.StartSet(tt.NonOptional().Field(0).Type, len(m.GenLanguages))
			if err != nil {
				return err
			}
			for key7 := range m.GenLanguages {
				keyTarget6, err := setTarget5.StartKey()
				if err != nil {
					return err
				}

				if err := key7.FillVDLTarget(keyTarget6, tt.NonOptional().Field(0).Type.Key()); err != nil {
					return err
				}
				if err := setTarget5.FinishKey(keyTarget6); err != nil {
					return err
				}
			}
			if err := fieldTarget3.FinishSet(setTarget5); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var10 := true
	var var11 bool
	if len(m.Go.WireToNativeTypes) == 0 {
		var11 = true
	}
	var10 = var10 && var11
	if var10 {
		if err := fieldsTarget1.ZeroField("Go"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("Go")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Go.FillVDLTarget(fieldTarget9, tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
				return err
			}
		}
	}
	var14 := true
	var var15 bool
	if len(m.Java.WireToNativeTypes) == 0 {
		var15 = true
	}
	var14 = var14 && var15
	var var16 bool
	if len(m.Java.WireTypeRenames) == 0 {
		var16 = true
	}
	var14 = var14 && var16
	if var14 {
		if err := fieldsTarget1.ZeroField("Java"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget12, fieldTarget13, err := fieldsTarget1.StartField("Java")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Java.FillVDLTarget(fieldTarget13, tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget12, fieldTarget13); err != nil {
				return err
			}
		}
	}
	var19 := (m.Javascript == JavascriptConfig{})
	if var19 {
		if err := fieldsTarget1.ZeroField("Javascript"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget17, fieldTarget18, err := fieldsTarget1.StartField("Javascript")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Javascript.FillVDLTarget(fieldTarget18, tt.NonOptional().Field(3).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget17, fieldTarget18); err != nil {
				return err
			}
		}
	}
	var22 := true
	var var23 bool
	if len(m.Swift.WireToNativeTypes) == 0 {
		var23 = true
	}
	var22 = var22 && var23
	if var22 {
		if err := fieldsTarget1.ZeroField("Swift"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget20, fieldTarget21, err := fieldsTarget1.StartField("Swift")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Swift.FillVDLTarget(fieldTarget21, tt.NonOptional().Field(4).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget20, fieldTarget21); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *Config) MakeVDLTarget() vdl.Target {
	return nil
}

type ConfigTarget struct {
	Value *Config

	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *ConfigTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*Config)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *ConfigTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "GenLanguages":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.GenLanguages))
		return nil, target, err
	case "Go":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Go))
		return nil, target, err
	case "Java":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Java))
		return nil, target, err
	case "Javascript":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Javascript))
		return nil, target, err
	case "Swift":
		target, err := vdl.ReflectTarget(reflect.ValueOf(&t.Value.Swift))
		return nil, target, err
	default:
		return nil, nil, vdl.ErrFieldNoExist
	}
}
func (t *ConfigTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *ConfigTarget) ZeroField(name string) error {
	switch name {
	case "GenLanguages":
		t.Value.GenLanguages = map[GenLanguage]struct{}(nil)
		return nil
	case "Go":
		t.Value.Go = GoConfig{}
		return nil
	case "Java":
		t.Value.Java = JavaConfig{}
		return nil
	case "Javascript":
		t.Value.Javascript = JavascriptConfig{}
		return nil
	case "Swift":
		t.Value.Swift = SwiftConfig{}
		return nil
	default:
		return vdl.ErrFieldNoExist
	}
}
func (t *ConfigTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x Config) VDLIsZero() bool {
	if len(x.GenLanguages) != 0 {
		return false
	}
	if !x.Go.VDLIsZero() {
		return false
	}
	if !x.Java.VDLIsZero() {
		return false
	}
	if x.Javascript != (JavascriptConfig{}) {
		return false
	}
	if !x.Swift.VDLIsZero() {
		return false
	}
	return true
}

func (x Config) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*Config)(nil)).Elem()); err != nil {
		return err
	}
	if len(x.GenLanguages) != 0 {
		if err := enc.NextField("GenLanguages"); err != nil {
			return err
		}
		if err := __VDLWriteAnon_set_4(enc, x.GenLanguages); err != nil {
			return err
		}
	}
	if !x.Go.VDLIsZero() {
		if err := enc.NextField("Go"); err != nil {
			return err
		}
		if err := x.Go.VDLWrite(enc); err != nil {
			return err
		}
	}
	if !x.Java.VDLIsZero() {
		if err := enc.NextField("Java"); err != nil {
			return err
		}
		if err := x.Java.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Javascript != (JavascriptConfig{}) {
		if err := enc.NextField("Javascript"); err != nil {
			return err
		}
		if err := x.Javascript.VDLWrite(enc); err != nil {
			return err
		}
	}
	if !x.Swift.VDLIsZero() {
		if err := enc.NextField("Swift"); err != nil {
			return err
		}
		if err := x.Swift.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_set_4(enc vdl.Encoder, x map[GenLanguage]struct{}) error {
	if err := enc.StartValue(vdl.TypeOf((*map[GenLanguage]struct{})(nil))); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for key := range x {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := key.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *Config) VDLRead(dec vdl.Decoder) error {
	*x = Config{}
	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 "GenLanguages":
			if err := __VDLReadAnon_set_4(dec, &x.GenLanguages); err != nil {
				return err
			}
		case "Go":
			if err := x.Go.VDLRead(dec); err != nil {
				return err
			}
		case "Java":
			if err := x.Java.VDLRead(dec); err != nil {
				return err
			}
		case "Javascript":
			if err := x.Javascript.VDLRead(dec); err != nil {
				return err
			}
		case "Swift":
			if err := x.Swift.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_set_4(dec vdl.Decoder, x *map[GenLanguage]struct{}) 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 set %T, from %v", *x, dec.Type())
	}
	var tmpMap map[GenLanguage]struct{}
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(map[GenLanguage]struct{}, len)
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		}
		var key GenLanguage
		{
			if err := key.VDLRead(dec); err != nil {
				return err
			}
		}
		if tmpMap == nil {
			tmpMap = make(map[GenLanguage]struct{})
		}
		tmpMap[key] = struct{}{}
	}
}

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((*GenLanguage)(nil))
	vdl.Register((*GoKind)(nil))
	vdl.Register((*GoImport)(nil))
	vdl.Register((*GoZeroMode)(nil))
	vdl.Register((*GoZero)(nil))
	vdl.Register((*GoType)(nil))
	vdl.Register((*GoConfig)(nil))
	vdl.Register((*JavaConfig)(nil))
	vdl.Register((*JavascriptConfig)(nil))
	vdl.Register((*SwiftConfig)(nil))
	vdl.Register((*Config)(nil))

	return struct{}{}
}
