{{$typesPackage := .TypesPackage}} // {{.Name}} type {{.Name}} struct { m {{$typesPackage}}Map ref *ref.Ref } func New{{.Name}}() {{.Name}} { return {{.Name}}{ {{$typesPackage}}NewMap( {{range .Fields}}{{if (not .Optional)}}{{$typesPackage}}NewString("{{.Name}}"), {{valueZero .T}}, {{end}}{{end}}{{if .HasUnion}}{{$typesPackage}}NewString("$unionIndex"), {{$typesPackage}}UInt32(0), {{$typesPackage}}NewString("$unionValue"), {{valueZero .UnionZeroType}},{{end}} ), &ref.Ref{}} } {{if .CanUseDef}} type {{.Name}}Def struct { {{range .Fields}}{{title .Name}} {{defType .T}} {{end}}{{if .HasUnion}}__unionIndex uint32 __unionValue interface{} {{end}}} func (def {{.Name}}Def) New() {{.Name}} { return {{.Name}}{ {{$typesPackage}}NewMap( {{range .Fields}}{{$typesPackage}}NewString("{{.Name}}"), {{defToValue (print "def." (title .Name)) .T}}, {{end}}{{if .HasUnion}}{{$typesPackage}}NewString("$unionIndex"), {{$typesPackage}}UInt32(def.__unionIndex), {{$typesPackage}}NewString("$unionValue"), def.__unionDefToValue(), {{end}} ), &ref.Ref{}} } func (s {{.Name}}) Def() (d {{.Name}}Def) { {{range .Fields}}{{if .Optional}}if v, ok := s.m.MaybeGet({{$typesPackage}}NewString("{{.Name}}")); ok { d.{{title .Name}} = {{valueToDef "v" .T}} }{{else}}d.{{title .Name}} = {{valueToDef (printf `s.m.Get(%sNewString("%s"))` $typesPackage .Name) .T}}{{end}} {{end}}{{if .HasUnion}}d.__unionIndex = uint32(s.m.Get({{$typesPackage}}NewString("$unionIndex")).({{$typesPackage}}UInt32)) d.__unionValue = s.__unionValueToDef() {{end}}return } {{if .HasUnion}} func (def {{.Name}}Def) __unionDefToValue() {{$typesPackage}}Value { switch def.__unionIndex { {{range $index, $field := .Choices}}case {{$index}}: return {{defToValue (printf "def.__unionValue.(%s)" (defType .T)) .T}} {{end}}} panic("unreachable") } func (s {{.Name}}) __unionValueToDef() interface{} { switch uint32(s.m.Get({{$typesPackage}}NewString("$unionIndex")).({{$typesPackage}}UInt32)) { {{range $index, $field := .Choices}}case {{$index}}: return {{valueToDef (printf `s.m.Get(%sNewString("$unionValue"))` $typesPackage) .T}} {{end}}} panic("unreachable") } {{end}} {{end}} var __typeRefFor{{.Name}} {{$typesPackage}}TypeRef func (m {{.Name}}) TypeRef() {{$typesPackage}}TypeRef { return __typeRefFor{{.Name}} } func init() { __typeRefFor{{.Name}} = {{$typesPackage}}MakeTypeRef(__{{.PackageName}}PackageInFile_{{.FileID}}_CachedRef, {{.Ordinal}}) {{$typesPackage}}RegisterFromValFunction(__typeRefFor{{.Name}}, func(v {{$typesPackage}}Value) {{$typesPackage}}Value { return {{.Name}}FromVal(v) }) } func {{.Name}}FromVal(val {{$typesPackage}}Value) {{.Name}} { // TODO: Do we still need FromVal? if val, ok := val.({{.Name}}); ok { return val } // TODO: Validate here return {{.Name}}{val.({{$typesPackage}}Map), &ref.Ref{}} } func (s {{.Name}}) InternalImplementation() {{$typesPackage}}Map { return s.m } func (s {{.Name}}) Equals(other {{$typesPackage}}Value) bool { return other != nil && __typeRefFor{{.Name}}.Equals(other.TypeRef()) && s.Ref() == other.Ref() } func (s {{.Name}}) Ref() ref.Ref { return {{$typesPackage}}EnsureRef(s.ref, s) } func (s {{.Name}}) Chunks() (chunks []ref.Ref) { chunks = append(chunks, s.TypeRef().Chunks()...) chunks = append(chunks, s.m.Chunks()...) return } {{$name := .Name}} {{range $index, $field := .Fields}} {{if .Optional}} func (s {{$name}}) {{title .Name}}() (v {{userType .T}}, ok bool) { var vv {{$typesPackage}}Value if vv, ok = s.m.MaybeGet({{$typesPackage}}NewString("{{.Name}}")); ok { v = {{valueToUser "vv" .T}} } return } {{else}} func (s {{$name}}) {{title .Name}}() {{userType .T}} { return {{valueToUser (printf `s.m.Get(%sNewString("%s"))` $typesPackage .Name) .T}} } {{end}} func (s {{$name}}) Set{{title .Name}}(val {{userType .T}}) {{$name}} { return {{$name}}{s.m.Set({{$typesPackage}}NewString("{{.Name}}"), {{userToValue "val" .T}}), &ref.Ref{}} } {{end}} {{$canUseDef := .CanUseDef}} {{range $index, $field := .Choices}} func (s {{$name}}) {{title .Name}}() (val {{userType .T}}, ok bool) { if s.m.Get({{$typesPackage}}NewString("$unionIndex")).({{$typesPackage}}UInt32) != {{$index}} { return } return {{valueToUser (printf `s.m.Get(%sNewString("$unionValue"))` $typesPackage) .T}}, true } func (s {{$name}}) Set{{title .Name}}(val {{userType .T}}) {{$name}} { return {{$name}}{s.m.Set({{$typesPackage}}NewString("$unionIndex"), {{$typesPackage}}UInt32({{$index}})).Set({{$typesPackage}}NewString("$unionValue"), {{userToValue "val" .T}}), &ref.Ref{}} } {{if $canUseDef}} func (def {{$name}}Def) {{title .Name}}() (val {{defType .T}}, ok bool) { if def.__unionIndex != {{$index}} { return } return def.__unionValue.({{defType .T}}), true } func (def {{$name}}Def) Set{{title .Name}}(val {{defType .T}}) {{$name}}Def { def.__unionIndex = {{$index}} def.__unionValue = val return def } {{end}} {{end}}