Files
dolt/nomdl/codegen/struct.tmpl
Chris Masone 63c956a5c5 Add types.TypeRef
We want to explore encoding type information about Noms data in
the Noms database. So, we need some way to describe types. This
takes the shortest path to making a Noms type called "TypeRef" that
is a peer of Set, Map et al and can describe all the types we currently
use.
2015-09-22 16:19:38 -07:00

137 lines
4.2 KiB
Cheetah

// {{.Name}}
type {{.Name}} struct {
m types.Map
}
func New{{.Name}}() {{.Name}} {
return {{.Name}}{types.NewMap(
types.NewString("$name"), types.NewString("{{.Name}}"),
types.NewString("$type"), types.MakeTypeRef(types.NewString("{{.Name}}"), __{{.PackageName}}PackageInFile_{{.FileID}}_Ref()),
{{range .Fields}}types.NewString("{{title .Name}}"), {{valueZero .T}},
{{end}}{{if .HasUnion}}types.NewString("$unionIndex"), types.UInt32(0),
types.NewString("$unionValue"), {{valueZero .UnionZeroType}},{{end}}
)}
}
{{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}}{
types.NewMap(
types.NewString("$name"), types.NewString("{{.Name}}"),
types.NewString("$type"), types.MakeTypeRef(types.NewString("{{.Name}}"), __{{.PackageName}}PackageInFile_{{.FileID}}_Ref()),
{{range .Fields}}types.NewString("{{title .Name}}"), {{defToValue (print "def." (title .Name)) .T}},
{{end}}{{if .HasUnion}}types.NewString("$unionIndex"), types.UInt32(def.__unionIndex),
types.NewString("$unionValue"), def.__unionDefToValue(),
{{end}}
)}
}
func (self {{.Name}}) Def() {{.Name}}Def {
return {{.Name}}Def{
{{range .Fields}}{{valueToDef (printf `self.m.Get(types.NewString("%s"))` (title .Name)) .T}},
{{end}}{{if .HasUnion}}uint32(self.m.Get(types.NewString("$unionIndex")).(types.UInt32)),
self.__unionValueToDef(),{{end}}
}
}
{{if .HasUnion}}
func (def {{.Name}}Def) __unionDefToValue() types.Value {
switch def.__unionIndex {
{{range $index, $field := .Choices}}case {{$index}}:
return {{defToValue (printf "def.__unionValue.(%s)" (defType .T)) .T}}
{{end}}}
panic("unreachable")
}
func (self {{.Name}}) __unionValueToDef() interface{} {
switch uint32(self.m.Get(types.NewString("$unionIndex")).(types.UInt32)) {
{{range $index, $field := .Choices}}case {{$index}}:
return {{valueToDef `self.m.Get(types.NewString("$unionValue"))` .T}}
{{end}}}
panic("unreachable")
}
{{end}}
{{end}}
// Creates and returns a Noms Value that describes {{.Name}}.
func __typeRefOf{{.Name}}() types.TypeRef {
return types.MakeStructTypeRef(types.NewString("{{.Name}}"),
types.NewList(
{{range .Fields}}types.NewString("{{.Name}}"), {{toTypesTypeRef .T}},
{{end}}
),
{{if .HasUnion}}types.NewList(
{{range .Choices}}types.NewString("{{.Name}}"), {{toTypesTypeRef .T}},
{{end}}
){{else}}nil{{end}})
}
func {{.Name}}FromVal(val types.Value) {{.Name}} {
// TODO: Validate here
return {{.Name}}{val.(types.Map)}
}
func (self {{.Name}}) NomsValue() types.Value {
return self.m
}
func (self {{.Name}}) Equals(other {{.Name}}) bool {
return self.m.Equals(other.m)
}
func (self {{.Name}}) Ref() ref.Ref {
return self.m.Ref()
}
func (self {{.Name}}) Type() types.TypeRef {
return self.m.Get(types.NewString("$type")).(types.TypeRef)
}
{{$name := .Name}}
{{range $index, $field := .Fields}}
func (self {{$name}}) {{title .Name}}() {{userType .T}} {
return {{valueToUser (printf `self.m.Get(types.NewString("%s"))` (title .Name)) .T}}
}
func (self {{$name}}) Set{{title .Name}}(val {{userType .T}}) {{$name}} {
return {{$name}}{self.m.Set(types.NewString("{{title .Name}}"), {{userToValue "val" .T}})}
}
{{end}}
{{$canUseDef := .CanUseDef}}
{{range $index, $field := .Choices}}
func (self {{$name}}) {{title .Name}}() (val {{userType .T}}, ok bool) {
if self.m.Get(types.NewString("$unionIndex")).(types.UInt32) != {{$index}} {
return
}
return {{valueToUser `self.m.Get(types.NewString("$unionValue"))` .T}}, true
}
func (self {{$name}}) Set{{title .Name}}(val {{userType .T}}) {{$name}} {
return {{$name}}{self.m.Set(types.NewString("$unionIndex"), types.UInt32({{$index}})).Set(types.NewString("$unionValue"), {{userToValue "val" .T}})}
}
{{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}}