// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file was auto-generated by the vanadium vdl tool.
// Source: config.vdl

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

import (
	// VDL system imports
	"fmt"
	"v.io/v23/vdl"
)

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

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

func (m *Config) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {

	if __VDLType_config_vdltool_Config == nil || __VDLTypeconfig0 == nil {
		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
	}
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}

	var var2 bool
	if len(m.GenLanguages) == 0 {
		var2 = true
	}
	if !var2 {
		keyTarget3, fieldTarget4, err := fieldsTarget1.StartField("GenLanguages")
		if err != vdl.ErrFieldNoExist && err != nil {
			return err
		}
		if err != vdl.ErrFieldNoExist {

			setTarget5, err := fieldTarget4.StartSet(__VDLTypeconfig1, 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, __VDLType_config_vdltool_GenLanguage); err != nil {
					return err
				}
				if err := setTarget5.FinishKey(keyTarget6); err != nil {
					return err
				}
			}
			if err := fieldTarget4.FinishSet(setTarget5); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget3, fieldTarget4); err != nil {
				return err
			}
		}
	}
	var8 := m.Go.IsZero()
	if !var8 {
		keyTarget9, fieldTarget10, err := fieldsTarget1.StartField("Go")
		if err != vdl.ErrFieldNoExist && err != nil {
			return err
		}
		if err != vdl.ErrFieldNoExist {

			if err := m.Go.FillVDLTarget(fieldTarget10, __VDLType_config_vdltool_GoConfig); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget9, fieldTarget10); err != nil {
				return err
			}
		}
	}
	var11 := m.Java.IsZero()
	if !var11 {
		keyTarget12, fieldTarget13, err := fieldsTarget1.StartField("Java")
		if err != vdl.ErrFieldNoExist && err != nil {
			return err
		}
		if err != vdl.ErrFieldNoExist {

			if err := m.Java.FillVDLTarget(fieldTarget13, __VDLType_config_vdltool_JavaConfig); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget12, fieldTarget13); err != nil {
				return err
			}
		}
	}
	var14 := m.Javascript.IsZero()
	if !var14 {
		keyTarget15, fieldTarget16, err := fieldsTarget1.StartField("Javascript")
		if err != vdl.ErrFieldNoExist && err != nil {
			return err
		}
		if err != vdl.ErrFieldNoExist {

			if err := m.Javascript.FillVDLTarget(fieldTarget16, __VDLType_config_vdltool_JavascriptConfig); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget15, fieldTarget16); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

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

func (m *Config) IsZero() bool {

	var1 := true
	var var2 bool
	if len(m.GenLanguages) == 0 {
		var2 = true
	}
	var1 = var1 && var2
	var3 := m.Go.IsZero()
	var1 = var1 && var3
	var4 := m.Java.IsZero()
	var1 = var1 && var4
	var5 := m.Javascript.IsZero()
	var1 = var1 && var5
	return var1
}

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

const (
	GenLanguageGo GenLanguage = iota
	GenLanguageJava
	GenLanguageJavascript
)

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

// 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
	}
	*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"
	}
	return ""
}

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

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

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

func (m GenLanguage) IsZero() bool {

	var1 := (m == GenLanguageGo)
	return var1
}

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

	if __VDLType_config_vdltool_GoConfig == nil || __VDLTypeconfig2 == nil {
		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
	}
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}

	var var2 bool
	if len(m.WireToNativeTypes) == 0 {
		var2 = true
	}
	if !var2 {
		keyTarget3, fieldTarget4, err := fieldsTarget1.StartField("WireToNativeTypes")
		if err != vdl.ErrFieldNoExist && err != nil {
			return err
		}
		if err != vdl.ErrFieldNoExist {

			mapTarget5, err := fieldTarget4.StartMap(__VDLTypeconfig3, 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), vdl.StringType); err != nil {
					return err
				}
				valueTarget8, err := mapTarget5.FinishKeyStartField(keyTarget6)
				if err != nil {
					return err
				}

				if err := value9.FillVDLTarget(valueTarget8, __VDLType_config_vdltool_GoType); err != nil {
					return err
				}
				if err := mapTarget5.FinishField(keyTarget6, valueTarget8); err != nil {
					return err
				}
			}
			if err := fieldTarget4.FinishMap(mapTarget5); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget3, fieldTarget4); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

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

func (m *GoConfig) IsZero() bool {

	var1 := true
	var var2 bool
	if len(m.WireToNativeTypes) == 0 {
		var2 = true
	}
	var1 = var1 && var2
	return var1
}

// 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 {
	// 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.
	Type string
	// Imports are the Go imports to use in generated code, required by the Type.
	Imports []GoImport
}

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

func (m *GoType) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {

	if __VDLType_config_vdltool_GoType == nil || __VDLTypeconfig4 == nil {
		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
	}
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}

	var2 := (m.Type == "")
	if !var2 {
		keyTarget3, fieldTarget4, err := fieldsTarget1.StartField("Type")
		if err != vdl.ErrFieldNoExist && err != nil {
			return err
		}
		if err != vdl.ErrFieldNoExist {
			if err := fieldTarget4.FromString(string(m.Type), vdl.StringType); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget3, fieldTarget4); err != nil {
				return err
			}
		}
	}
	var var5 bool
	if len(m.Imports) == 0 {
		var5 = true
	}
	if !var5 {
		keyTarget6, fieldTarget7, err := fieldsTarget1.StartField("Imports")
		if err != vdl.ErrFieldNoExist && err != nil {
			return err
		}
		if err != vdl.ErrFieldNoExist {

			listTarget8, err := fieldTarget7.StartList(__VDLTypeconfig5, len(m.Imports))
			if err != nil {
				return err
			}
			for i, elem10 := range m.Imports {
				elemTarget9, err := listTarget8.StartElem(i)
				if err != nil {
					return err
				}

				if err := elem10.FillVDLTarget(elemTarget9, __VDLType_config_vdltool_GoImport); err != nil {
					return err
				}
				if err := listTarget8.FinishElem(elemTarget9); err != nil {
					return err
				}
			}
			if err := fieldTarget7.FinishList(listTarget8); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget6, fieldTarget7); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

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

func (m *GoType) IsZero() bool {

	var1 := true
	var2 := (m.Type == "")
	var1 = var1 && var2
	var var3 bool
	if len(m.Imports) == 0 {
		var3 = true
	}
	var1 = var1 && var3
	return var1
}

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

	if __VDLType_config_vdltool_GoImport == nil || __VDLTypeconfig6 == nil {
		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
	}
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}

	var2 := (m.Path == "")
	if !var2 {
		keyTarget3, fieldTarget4, err := fieldsTarget1.StartField("Path")
		if err != vdl.ErrFieldNoExist && err != nil {
			return err
		}
		if err != vdl.ErrFieldNoExist {
			if err := fieldTarget4.FromString(string(m.Path), vdl.StringType); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget3, fieldTarget4); err != nil {
				return err
			}
		}
	}
	var5 := (m.Name == "")
	if !var5 {
		keyTarget6, fieldTarget7, err := fieldsTarget1.StartField("Name")
		if err != vdl.ErrFieldNoExist && err != nil {
			return err
		}
		if err != vdl.ErrFieldNoExist {
			if err := fieldTarget7.FromString(string(m.Name), vdl.StringType); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget6, fieldTarget7); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

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

func (m *GoImport) IsZero() bool {

	var1 := (*m == GoImport{})
	return var1
}

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

	if __VDLType_config_vdltool_JavaConfig == nil || __VDLTypeconfig7 == nil {
		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
	}
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}

	var var2 bool
	if len(m.WireToNativeTypes) == 0 {
		var2 = true
	}
	if !var2 {
		keyTarget3, fieldTarget4, err := fieldsTarget1.StartField("WireToNativeTypes")
		if err != vdl.ErrFieldNoExist && err != nil {
			return err
		}
		if err != vdl.ErrFieldNoExist {

			mapTarget5, err := fieldTarget4.StartMap(__VDLTypeconfig8, 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), vdl.StringType); err != nil {
					return err
				}
				valueTarget8, err := mapTarget5.FinishKeyStartField(keyTarget6)
				if err != nil {
					return err
				}
				if err := valueTarget8.FromString(string(value9), vdl.StringType); err != nil {
					return err
				}
				if err := mapTarget5.FinishField(keyTarget6, valueTarget8); err != nil {
					return err
				}
			}
			if err := fieldTarget4.FinishMap(mapTarget5); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget3, fieldTarget4); err != nil {
				return err
			}
		}
	}
	var var10 bool
	if len(m.WireTypeRenames) == 0 {
		var10 = true
	}
	if !var10 {
		keyTarget11, fieldTarget12, err := fieldsTarget1.StartField("WireTypeRenames")
		if err != vdl.ErrFieldNoExist && err != nil {
			return err
		}
		if err != vdl.ErrFieldNoExist {

			mapTarget13, err := fieldTarget12.StartMap(__VDLTypeconfig8, 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), vdl.StringType); err != nil {
					return err
				}
				valueTarget16, err := mapTarget13.FinishKeyStartField(keyTarget14)
				if err != nil {
					return err
				}
				if err := valueTarget16.FromString(string(value17), vdl.StringType); err != nil {
					return err
				}
				if err := mapTarget13.FinishField(keyTarget14, valueTarget16); err != nil {
					return err
				}
			}
			if err := fieldTarget12.FinishMap(mapTarget13); 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 *JavaConfig) MakeVDLTarget() vdl.Target {
	return nil
}

func (m *JavaConfig) IsZero() bool {

	var1 := true
	var var2 bool
	if len(m.WireToNativeTypes) == 0 {
		var2 = true
	}
	var1 = var1 && var2
	var var3 bool
	if len(m.WireTypeRenames) == 0 {
		var3 = true
	}
	var1 = var1 && var3
	return var1
}

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

	if __VDLType_config_vdltool_JavascriptConfig == nil || __VDLTypeconfig9 == nil {
		panic("Initialization order error: types generated for FillVDLTarget not initialized. Consider moving caller to an init() block.")
	}
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}

	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

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

func (m *JavascriptConfig) IsZero() bool {

	var1 := (*m == JavascriptConfig{})
	return var1
}

func init() {
	vdl.Register((*Config)(nil))
	vdl.Register((*GenLanguage)(nil))
	vdl.Register((*GoConfig)(nil))
	vdl.Register((*GoType)(nil))
	vdl.Register((*GoImport)(nil))
	vdl.Register((*JavaConfig)(nil))
	vdl.Register((*JavascriptConfig)(nil))
}

var __VDLTypeconfig0 *vdl.Type = vdl.TypeOf((*Config)(nil))
var __VDLTypeconfig2 *vdl.Type = vdl.TypeOf((*GoConfig)(nil))
var __VDLTypeconfig6 *vdl.Type = vdl.TypeOf((*GoImport)(nil))
var __VDLTypeconfig4 *vdl.Type = vdl.TypeOf((*GoType)(nil))
var __VDLTypeconfig7 *vdl.Type = vdl.TypeOf((*JavaConfig)(nil))
var __VDLTypeconfig9 *vdl.Type = vdl.TypeOf((*JavascriptConfig)(nil))
var __VDLTypeconfig5 *vdl.Type = vdl.TypeOf([]GoImport(nil))
var __VDLTypeconfig8 *vdl.Type = vdl.TypeOf(map[string]string(nil))
var __VDLTypeconfig3 *vdl.Type = vdl.TypeOf(map[string]GoType(nil))
var __VDLTypeconfig1 *vdl.Type = vdl.TypeOf(map[GenLanguage]struct{}(nil))
var __VDLType_config_vdltool_Config *vdl.Type = vdl.TypeOf(Config{})
var __VDLType_config_vdltool_GenLanguage *vdl.Type = vdl.TypeOf(GenLanguageGo)
var __VDLType_config_vdltool_GoConfig *vdl.Type = vdl.TypeOf(GoConfig{})
var __VDLType_config_vdltool_GoImport *vdl.Type = vdl.TypeOf(GoImport{})
var __VDLType_config_vdltool_GoType *vdl.Type = vdl.TypeOf(GoType{})
var __VDLType_config_vdltool_JavaConfig *vdl.Type = vdl.TypeOf(JavaConfig{})
var __VDLType_config_vdltool_JavascriptConfig *vdl.Type = vdl.TypeOf(JavascriptConfig{})

func __VDLEnsureNativeBuilt_config() {
}
