Files
dolt/nomdl/codegen/struct.tmpl
Erik Arvidsson 30cc7d518f Make Equals compare by Ref (after comparing TypeRef)
This changes equal to compare by ref. Since computing the ref can be
expensive we first check that the type refs are equal.

Fixes #532
2015-10-30 16:50:49 -04:00

151 lines
4.9 KiB
Cheetah

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