diff --git a/entc/entc.go b/entc/entc.go index 727a5a771..bab22adb9 100644 --- a/entc/entc.go +++ b/entc/entc.go @@ -141,7 +141,7 @@ func TemplateDir(path string) Option { if err != nil { return fmt.Errorf("load template: %v", err) } - if info.IsDir() { + if info.IsDir() || strings.HasSuffix(path, ".go") { return nil } cfg.Template, err = cfg.Template.ParseFiles(path) diff --git a/entc/gen/func.go b/entc/gen/func.go index 6ad3926bb..0f231716f 100644 --- a/entc/gen/func.go +++ b/entc/gen/func.go @@ -65,6 +65,7 @@ var ( "hasKey": hasKey, "list": list, "fail": fail, + "replace": strings.ReplaceAll, } rules = ruleset() acronyms = make(map[string]struct{}) diff --git a/entc/gen/type.go b/entc/gen/type.go index 521e017fc..16e5dc2ee 100644 --- a/entc/gen/type.go +++ b/entc/gen/type.go @@ -75,6 +75,9 @@ type ( // UserDefined indicates that this field was defined by the loaded schema. // Unlike default id field, which is defined by the generator. UserDefined bool + // Annotations that were defined in the field schema. + // The mapping is from the Annotation.Name() to the decoded object. + Annotations map[string]interface{} } // Edge of a graph between two types. @@ -176,6 +179,7 @@ func NewType(c *Config, schema *load.Schema) (*Type, error) { StructTag: structTag(f.Name, f.Tag), Validators: f.Validators, UserDefined: true, + Annotations: f.Annotations, } if err := typ.checkField(tf, f); err != nil { return nil, err diff --git a/entc/integration/ent/extension.go b/entc/integration/ent/extension.go new file mode 100644 index 000000000..6a4aa227c --- /dev/null +++ b/entc/integration/ent/extension.go @@ -0,0 +1,13 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// CardExtension is a type for holding the extension information defined in the schema. +type CardExtension struct { + Number string + Name string +} diff --git a/entc/integration/ent/schema/card.go b/entc/integration/ent/schema/card.go index 045de3506..5bde32ffe 100644 --- a/entc/integration/ent/schema/card.go +++ b/entc/integration/ent/schema/card.go @@ -6,6 +6,7 @@ package schema import ( "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/entc/integration/ent/template" "github.com/facebookincubator/ent/schema/edge" "github.com/facebookincubator/ent/schema/field" "github.com/facebookincubator/ent/schema/mixin" @@ -27,11 +28,17 @@ func (Card) Fields() []ent.Field { return []ent.Field{ field.String("number"). Immutable(). - NotEmpty(), + NotEmpty(). + Annotations(&template.Extension{ + Type: "string", + }), field.String("name"). Optional(). Comment("Exact name written on card"). - NotEmpty(), + NotEmpty(). + Annotations(&template.Extension{ + Type: "string", + }), } } diff --git a/entc/integration/ent/template/ext.go b/entc/integration/ent/template/ext.go new file mode 100644 index 000000000..b7e74a4ce --- /dev/null +++ b/entc/integration/ent/template/ext.go @@ -0,0 +1,14 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +package template + +// Extension is a template extension. +type Extension struct { + Type string +} + +func (*Extension) Name() string { + return "Extension" +} diff --git a/entc/integration/ent/template/ext.tmpl b/entc/integration/ent/template/ext.tmpl new file mode 100644 index 000000000..ba95317db --- /dev/null +++ b/entc/integration/ent/template/ext.tmpl @@ -0,0 +1,27 @@ +{{/* +Copyright 2019-present Facebook Inc. All rights reserved. +This source code is licensed under the Apache 2.0 license found +in the LICENSE file in the root directory of this source tree. +*/}} + +{{ define "extension" }} +{{ $pkg := base $.Config.Package }} +{{ template "header" $ }} + +{{ range $n := $.Nodes }} + {{ $hasExt := false }} + {{ range $f := $n.Fields }}{{ if $f.Annotations.Extension }}{{ $hasExt = true }}{{ end }}{{ end }} + {{/* If one or fields contain the "Extension" annotation */}} + {{ if $hasExt }} + // {{ $n.Name }}Extension is a type for holding the extension information defined in the schema. + type {{ $n.Name }}Extension struct { + {{- range $f := $n.Fields }} + {{- with $ant := $f.Annotations.Extension }} + {{ $f.StructField }} {{ $ant.Type }} + {{- end }} + {{- end }} + } + {{ end }} +{{ end }} + +{{ end }} \ No newline at end of file diff --git a/entc/integration/gremlin/ent/extension.go b/entc/integration/gremlin/ent/extension.go new file mode 100644 index 000000000..6a4aa227c --- /dev/null +++ b/entc/integration/gremlin/ent/extension.go @@ -0,0 +1,13 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by entc, DO NOT EDIT. + +package ent + +// CardExtension is a type for holding the extension information defined in the schema. +type CardExtension struct { + Number string + Name string +} diff --git a/entc/integration/integration_test.go b/entc/integration/integration_test.go index 5f61be78f..b40f86aac 100644 --- a/entc/integration/integration_test.go +++ b/entc/integration/integration_test.go @@ -1115,6 +1115,12 @@ func Mutation(t *testing.T, client *ent.Client) { require.Equal(t, "boring", usr.Name) } +// Test templates codegen. +var ( + _ = ent.CardExtension{} + _ = ent.Card{}.StaticField +) + func drop(t *testing.T, client *ent.Client) { t.Log("drop data from database") ctx := context.Background() diff --git a/entc/integration/template/ent/template/node.tmpl b/entc/integration/template/ent/template/node.tmpl index 4705cb580..05883981d 100644 --- a/entc/integration/template/ent/template/node.tmpl +++ b/entc/integration/template/ent/template/node.tmpl @@ -43,7 +43,7 @@ type Edge struct { } {{/* loop over all types and add implement the Node interface. */}} -{{ range $_, $n := $.Nodes -}} +{{ range $n := $.Nodes -}} {{ $receiver := $n.Receiver }} func ({{ $receiver }} *{{ $n.Name }}) Node(ctx context.Context) (node *Node, err error) { node = &Node{ diff --git a/entc/load/internal/bindata.go b/entc/load/internal/bindata.go index ea126453f..435b73ab4 100644 --- a/entc/load/internal/bindata.go +++ b/entc/load/internal/bindata.go @@ -98,7 +98,7 @@ func templateMainTmpl() (*asset, error) { return a, nil } -var _schemaGo = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x5a\x5f\x6f\xdc\x36\x12\x7f\x5e\x7d\x8a\x89\x81\x1a\x52\xb0\xd5\xf6\x8a\xa2\xb8\xdb\xdc\x1e\x50\xb4\x29\xea\xeb\xd5\x0d\x9a\xa4\x2f\x41\x90\xca\xd2\x68\x97\xb1\x44\x6e\x49\xae\x63\xd7\xf5\x77\x3f\x70\x86\x94\x28\xad\x76\x9d\x7f\xf6\x4b\xa4\xe1\x0c\x67\xe6\xc7\xe1\xf0\x27\x6e\x16\x0b\xf8\x5e\x6d\x6f\xb4\x58\x6f\x2c\x7c\xfd\xd5\x3f\xfe\xf5\xe5\x56\xa3\x41\x69\xe1\xc7\xa2\xc4\x0b\xa5\x2e\xe1\x4c\x96\x39\x7c\xd7\x34\x40\x4a\x06\xdc\xb8\xbe\xc2\x2a\x4f\x16\x0b\x78\xb1\x11\x06\x8c\xda\xe9\x12\xa1\x54\x15\x82\x30\xd0\x88\x12\xa5\xc1\x0a\x76\xb2\x42\x0d\x76\x83\xf0\xdd\xb6\x28\x37\x08\x5f\xe7\x5f\x85\x51\xa8\xd5\x4e\x56\x6e\x0a\x21\x49\xe5\x7f\x67\xdf\x3f\x3d\x7f\xfe\x14\x6a\xd1\x60\x90\x69\xa5\x2c\x54\x42\x63\x69\x95\xbe\x01\x55\x83\x8d\xfc\x59\x8d\x98\x27\xc9\xb6\x28\x2f\x8b\x35\x42\xa3\x8a\x2a\x49\x44\xbb\x55\xda\x42\x9a\xcc\x4e\x50\x96\xaa\x12\x72\xbd\x78\x6b\x94\x3c\x49\x66\x27\x75\x6b\xdd\x3f\x1a\xeb\x06\x4b\x7b\x92\x24\xb3\x93\xb5\xb0\x9b\xdd\x45\x5e\xaa\x76\x51\xfb\x84\x85\x2c\x77\x17\x85\x55\x7a\x81\x92\xf4\xef\xd3\x59\x98\x72\x83\x6d\xb1\xc0\x6a\x8d\x1f\xa2\x5f\x0b\x6c\xaa\x0f\x31\x10\xb2\xc2\xeb\x93\x24\x4b\x1c\x6c\xcf\x49\x06\x1a\xfd\x82\x19\x28\x24\xa0\xb4\xb9\x1f\xb0\x9b\xc2\xc2\xbb\xc2\x10\x2e\x58\x41\xad\x55\x0b\x05\x94\xaa\xdd\x36\xc2\x2d\x8e\x41\x0d\x1e\xbb\x3c\xb1\x37\x5b\x0c\x53\x1a\xab\x77\xa5\x85\xdb\x64\x76\x5e\xb4\x08\x00\x4e\x22\xe4\x1a\xe8\xef\x0f\x87\xe6\xf2\x44\x16\x2d\xce\x55\x2b\x2c\xb6\x5b\x7b\x73\xf2\x47\x32\xfb\x5e\xc9\x5a\xac\x81\x62\x08\xcf\x5e\xb9\xa4\xd7\xa1\xfa\xd3\x6a\x8d\x06\x00\x5e\xbd\x7e\xec\x1e\xe3\xb9\x1d\x90\x66\xa8\xfd\xa3\xc3\xca\x90\x36\x3d\x46\xda\x04\xe3\x48\xfd\xcc\x21\x85\xc6\xa9\xd3\x63\xa4\x2e\x78\x68\xa8\xff\x93\x52\x97\x3e\x98\x67\xca\x08\x2b\x94\x0c\xfa\x1b\x37\x34\xd4\x7e\xa6\x1a\x51\xde\x00\x5c\x28\xd5\x00\x0c\x60\xd9\xd2\xd0\x40\xfd\x8e\x96\xab\x9b\xb6\x42\x53\x6a\x71\x81\x06\x0a\xa0\xd0\x61\x1b\x86\x7c\xd5\xf3\x6a\xfb\x35\xe9\xec\xfa\x55\xe9\x32\x02\x10\xd2\x02\x2c\x16\xc0\x98\x50\x6a\x61\x16\x9e\xbb\x11\xc6\xe6\xc9\xec\x17\x71\x8d\xd5\x99\x74\x26\x14\xf4\x62\x01\x67\xb2\x12\x65\x61\xd1\x80\xa8\x23\x03\x57\x31\xad\xd3\xfe\x52\x48\x36\x14\xf2\xcc\xcf\xcb\xbe\x48\x34\xf4\xd5\x92\x88\x7d\x71\xba\x1c\xd0\x7e\x71\xb2\xfc\x23\x6a\x93\x0d\xf7\x4b\x93\xff\xe2\x02\xbd\xa7\x4c\xcf\x64\xad\x7a\xb5\xc7\x94\x75\xfe\xe2\x66\x8b\x7e\xc0\x1b\x3a\xa7\x43\xc3\x17\x45\xec\xe0\xa0\x47\x5b\x8c\x0a\xfd\xb9\xf8\x2b\x8a\xf4\xb1\x90\xf6\xdb\x6f\x26\xec\x8c\xf8\x6b\xe4\xf0\xa9\xdc\xb5\xa6\x53\x7b\xf5\x7a\xec\x32\xec\x16\xa7\x36\xb4\x7c\x29\xc5\x9f\xbb\xce\x69\x5c\xa6\x03\xcb\x1d\xa9\x0d\x4d\xcf\x45\xd3\x14\x17\x0d\xde\x63\x2a\xbd\xda\xd0\xf8\xd7\xad\x2b\xd5\xa2\xb9\xc7\x58\x79\xb5\xa1\xf1\x0f\x58\x17\xbb\xc6\xde\x17\x74\xc5\x6a\x93\xb6\xbf\x17\x8d\x4b\x5b\x48\x8b\xda\x75\xd2\xdb\xbb\x49\xdb\x37\x57\x4e\x6f\x04\xd9\xb6\x2a\x2c\x86\x18\x0e\x43\x46\x6a\x6f\x26\x83\x38\x6b\xdb\x9d\xed\xb0\x3b\x38\x85\x08\x6a\x43\xeb\xdf\x8b\x46\x54\xae\xe3\xd3\x92\xd3\x66\x9b\xb2\xbe\xea\xd4\x46\x55\x66\x95\x2e\xd6\xf8\x33\xde\xc0\xb1\xea\x34\xac\xf6\xe6\x12\x6f\xc6\x3d\xcd\xf7\x19\xfa\x7b\x3c\x7c\x8d\xfb\x1b\xcb\x47\xce\x51\x3a\xf1\xd5\x3d\x99\x9b\xa0\x36\xb2\xa6\x7e\xe7\xb6\xa0\xd3\x6d\x8b\xed\x2b\x0e\x3f\x14\x7c\xb0\x26\xb5\x37\x7b\x1b\x93\x1b\x0e\x9d\x21\xfb\xfd\x86\xc4\x1f\xd1\x6e\xc8\x6e\xb2\xdb\xec\x41\x7b\xb0\xd3\x84\x8c\x8e\x18\x1d\xed\x32\x07\x8d\xc6\x1d\xe6\x37\xac\xa7\x4e\xea\xd8\x46\x63\xfd\x66\x3f\xc2\xdf\xb0\x0e\x7a\xfd\x21\xbc\x67\x78\xb0\xb7\xec\x2d\xf4\x91\xbe\x72\x26\xaf\x50\x1b\x3c\x66\x26\x58\x65\x1c\xe2\x9f\x3b\xa1\xb1\x3a\x62\xa7\xbd\xca\xc1\x0d\xf1\xd8\x11\x8a\x3c\x12\xdc\xb3\x19\xb8\xa2\xf8\xd4\xdb\x2f\x29\x96\x7f\x44\x4d\xb1\x61\x5f\x54\x53\x48\x1e\x41\x30\x10\xa6\xf8\x2c\xb8\x9f\x30\x4d\x68\x4f\x11\xa6\x08\x9c\xae\x84\xde\x0b\xa5\x73\x7c\x47\x95\x53\x6a\x24\x32\x51\xc8\x80\x88\x0b\x8a\x61\xa1\x27\xe6\x3d\x5b\xab\x74\x9e\xd4\x3b\x59\x06\xcb\x14\x2b\xbf\x40\x3f\x74\x1a\x99\x2f\xc7\xdb\x64\x26\x11\x96\x2b\x38\x75\xaf\xb7\xc9\xcc\x6d\x8f\x65\x58\x7e\xac\xf2\x17\xc5\x7a\xee\xa4\x37\x5b\x5c\x46\x52\xb7\xab\x92\x19\xed\xda\x48\xec\x5e\x9d\x98\x71\x5f\x06\x31\xbf\xba\x01\x5f\xa3\x4b\x3f\xe0\x5f\xdd\x48\xa8\xc2\x25\x8f\x84\x57\x1e\xaa\x3b\x3f\x34\x54\x07\x3f\x3d\xa6\x4b\x37\xd2\xbf\xce\x93\xd9\x5d\x32\x13\x35\x68\xac\x5d\x76\x6c\xf6\x84\x5e\x1f\xad\x40\x8a\xc6\x65\x3e\x93\xe8\xc4\xb0\xea\x90\xd2\x58\x67\x2c\x8f\x96\x6b\x05\xac\x17\xc9\x68\x7a\x8d\x76\xa7\x25\x48\xec\x17\x8a\x39\xd4\xfe\x4a\x31\xf3\xa3\xa5\xe2\xc7\xa9\xb5\x22\xe3\xb4\xae\x02\x65\x8a\x57\x2b\x65\x52\x3e\x07\xd4\xda\xbd\xdf\x52\x76\xa8\xb5\xcb\xae\xae\xf2\xa7\x5a\xa7\xd9\x13\x12\x44\xf9\x85\x08\x45\x33\x87\xba\xb5\x4e\x4b\xe9\x3a\xe5\xfa\x84\x2f\xfe\x5c\xc2\x17\x57\x27\x73\x67\x4f\x88\x3a\xf3\x8c\x52\x33\x84\xda\x29\xf9\xbc\x1d\xad\x33\x40\x67\x40\x2b\x5a\xab\xe1\x88\x93\xcc\x47\x85\xc4\x23\xbe\x96\x88\x75\x2d\xe3\x01\x92\x8c\x0b\x87\x87\xfa\xda\x09\xbc\x69\xd9\xc7\x10\x28\x52\x32\xeb\x88\x51\x3f\x1a\x24\x6e\xd4\xb3\x8e\x65\x3f\x6f\xe0\x21\x8c\x16\xf9\x8e\xf9\xc9\x92\x7c\x0f\x18\x4b\xaf\xd9\xd1\x90\x65\x97\x73\xc7\x38\x46\x55\xc9\xc3\x83\xc2\x8c\x78\x08\x8d\x37\x28\xd3\xba\xca\x7b\x69\x46\x93\x84\x93\xbc\xf3\xd1\x49\x68\xb8\x3b\xd1\x3b\x1f\x9d\xa4\x2b\x7e\x53\xd3\x62\xc0\xea\xfe\x8a\x68\x85\x31\xae\x27\x51\x1b\x15\xce\xa8\x56\x1a\x42\x9d\x9c\xcc\xdd\x5c\x6e\xc9\xb3\x6e\x6e\xc7\xb9\x97\x2b\x20\xb2\xed\xe2\x77\x24\x3c\x7b\xc2\xf2\x47\x2b\xf8\x8a\xdc\x99\x9a\xe4\xb0\x82\x53\x37\x40\xc6\xae\xf1\xf3\xf7\x90\xe7\x78\x40\x64\x11\xca\x42\xc2\x05\x02\xdd\x29\x60\x05\x56\x91\xce\x1a\x25\xea\x82\xf6\x89\xb3\xfc\x51\x69\xc0\xeb\xa2\xdd\x36\x38\x07\xa9\xac\xfb\xc4\xdb\xc9\x92\x88\x54\x23\x2e\x11\xac\x68\x31\x3f\x57\xef\x72\x8a\xf2\xcd\x3c\xec\x11\xd7\x69\xf3\x5f\x0a\x6d\x36\x45\x93\xf6\xeb\xef\xf7\x4c\x84\x90\xa9\xf3\x01\xd7\x5d\x45\xd5\x12\x6f\x7b\x53\xcf\x9d\x4d\xbf\xf7\xf9\xf0\xd9\xdf\xfb\xfc\x1d\x47\x7b\x9f\x1f\xa7\xf6\x3e\x19\xa7\xa2\xba\x76\x9f\x2f\x15\x5e\x0f\x5b\x35\x4f\x7d\xdb\xf9\x3e\x25\x81\x8b\x96\x8e\x2c\x5f\xd6\xa2\xba\x26\x36\x46\x3b\x89\x4f\xa7\x65\x37\xc0\xef\xe3\x3d\xe6\x46\xfa\x1d\x16\x17\xae\x1b\x19\xf5\x53\xce\xd4\x63\xe8\x6f\x32\x78\xb5\x68\xa5\xa2\x9b\x91\xee\xf3\xc0\x3d\x29\x28\xe0\xbf\xcf\x7f\x3d\x77\xc6\x74\xa6\xfb\x85\xae\x90\x17\x9a\x54\xdc\x04\xde\x58\x5d\xbc\xc5\xd2\xfa\x7f\x3c\x42\x03\xa7\xa9\x09\xbe\x1d\x55\xf0\x9e\x32\x48\x2f\xe0\xd5\xeb\x8b\x1b\xcb\x7d\x2c\x6a\x94\x86\x7a\x19\xdb\x3a\xcc\xf8\xea\x64\x19\x6e\x01\xf8\x35\xcd\xe2\xf3\x4c\x48\xbe\x13\x4b\xfd\x4d\x16\x1d\x78\xbf\xd6\xde\x73\x96\xd1\x5e\x20\x93\xbb\xb8\x11\x9b\xdc\xad\x39\x7d\xbe\x07\xd5\xf7\xee\xc9\x3e\xa9\xae\x29\x9b\x71\x4f\x1e\xbb\xe1\x15\xfd\xfc\x7e\x98\xea\x74\xbe\x8a\x1a\xa9\xa8\x82\xa3\x2e\x90\xcf\xe1\xcb\x35\x19\xb7\x47\x9d\x27\x5d\xc8\x35\x12\x93\x31\xbc\x11\xb9\x98\x61\x05\xc5\x76\x8b\xb2\x4a\xbd\x60\xde\xf3\x9a\x68\x97\xa4\x59\xe6\x61\xf2\xb7\x4f\x71\x02\xfe\xb2\xea\x21\x53\x70\x5b\xb7\x4b\xc2\xc7\xe0\xd3\x08\x57\x65\x51\x22\x67\x21\xc8\x78\xeb\x4f\x66\x33\x5a\x74\xba\x46\x7b\xf8\xda\xe2\xfb\xb7\xcf\xef\xc7\x1b\x0e\x9a\xb1\xc9\x7c\x67\x79\x29\xdb\x41\x6f\xe1\x06\x61\xf8\x18\x10\x57\x28\xe1\x62\x57\xd7\xa8\x81\x5a\x8a\xef\xae\xe1\x2a\x8f\xda\xc4\x68\x86\xf4\x62\x57\xfb\x9e\xe0\x18\x14\x0b\xe7\x87\x3a\xc3\x00\x06\x8a\xb0\x9b\xce\x4d\x34\x07\x73\x1c\x08\xd4\x3a\x2e\x88\xba\x2f\x07\xe3\xbb\x2f\x99\x44\xb4\x2d\xf7\x07\xa0\x99\xa0\x6e\xfb\x53\xbb\xb9\xa3\xe3\x27\x3e\x7d\xba\xae\x43\x4f\xc6\xdf\x16\x5a\xe5\xd1\xf1\xdf\x08\x71\xbb\xf4\x80\xa5\x06\x3c\x2c\x19\x8c\x5b\xd7\xb8\xbf\x12\x6c\x2e\x36\x9a\x7d\xb0\xbf\x06\x1d\xef\xc8\xee\x8a\x21\x12\x73\x68\xa3\x2d\xc3\x21\x13\x29\x77\x1f\xda\xc4\x2c\xa6\x7b\x70\x7b\xdd\xf5\xdf\x64\x36\xf3\x9f\x5a\x71\x34\xbe\x31\xb6\xd7\x59\x0f\xf7\x04\xb2\x43\xfa\xe3\xbc\x77\x75\x2b\xa3\xaa\x75\xf1\x52\xc0\x6f\x07\x6b\x5a\xf7\x2b\x3a\x73\x54\xc0\xfb\xef\x69\xfc\x70\x37\x3b\xb5\x89\x50\x3e\x34\x16\x0a\xc6\x51\x94\xee\xf6\x68\x05\xa7\xe1\x99\x67\xa4\x76\xe2\x19\xc1\xdb\x39\x89\xfc\xdd\x34\x09\xad\xe6\xb3\x7e\x16\x5d\x3c\x2f\x41\xcc\xfb\xc9\x43\xb1\x46\xed\xca\x93\x07\x30\x75\x00\xe4\xd0\x21\xf1\xb9\x41\x3f\x74\x38\x7c\xd4\xe9\x40\xb3\x1e\x3b\x1f\x1e\x20\xfa\x83\xe7\xc2\xa7\x1c\x0c\xe4\x80\x7f\x36\x89\xd3\xe0\xc3\xe1\xb3\xd7\x7d\x1f\x3f\xb9\x0c\xd1\xf3\x2f\x3a\x51\xec\x3f\x71\x40\x9f\xb1\x1e\xb3\x71\xd7\x1b\xb6\x3c\x5f\xa8\xdc\xf3\xf8\x5b\xe5\x23\x7a\xde\x80\x47\x1d\x6c\x7a\x87\xfb\xcc\x07\xb7\xbd\xe9\x2e\xf2\x7e\x4d\xe4\xf0\xb2\x76\x67\xc4\xc1\xf6\x10\xb0\x25\x9d\xfb\x76\xf9\x1e\xe6\x93\xd8\xc5\x74\xe4\x20\x74\x87\x0a\xf5\x03\x81\x9b\x2a\xc3\xf7\xad\xc2\xae\x08\xb9\xb0\xba\x02\xac\x8b\x86\xaf\x9f\xee\xde\x3b\xe5\x01\x35\x3a\x98\xb3\xff\x95\x32\x4e\x7a\xc8\xa9\xde\x23\x6b\x93\xfb\x9f\x41\x57\xc0\xd3\x79\xdd\xe9\x30\x6b\xe0\x2b\xa2\x0c\x7a\x56\xd1\xc7\x23\x6a\x78\xd4\x7d\xd8\xc2\xdf\x7f\xbb\xb7\x33\x59\xab\xfc\x7c\xd7\xa2\x16\x65\x9a\x8d\xf8\x0c\x45\x20\xe7\xa0\x2e\x99\xaa\xc4\xdf\xc4\x79\x5a\x37\xaa\xb0\xdf\x7e\xc3\x59\x3c\x52\x97\xb1\x71\xdc\x5f\x76\x12\xaf\xb7\x58\x5a\xac\x46\x1f\xfb\x74\xcf\xd0\x5d\x31\x2c\xf9\x8e\x21\xbe\x62\x30\xef\x84\x2d\x37\x60\xd9\x3b\x85\xea\xce\xff\x27\xce\x53\x59\x18\x04\x0b\xff\x59\x41\xfc\xdb\xa2\xfd\x27\x9c\x9e\x82\x85\x7f\x8f\xc4\xdf\x7e\xb3\x74\x9d\x6c\xfc\x55\xcf\x17\x17\x32\x9b\x9e\xee\xa5\x98\x9e\xef\xa5\x38\x38\xe1\xae\x9f\x71\xaa\x61\xf5\x1d\x03\xde\xe9\x62\x6b\xe2\x1f\xa2\xbd\xbc\x90\x15\xf3\xa0\x20\x68\xd1\x6e\x54\x05\xef\x84\xdd\x80\xc6\x52\x5d\x31\xf9\x45\x69\x76\x1a\x41\x2a\xd8\x16\x52\x94\x06\x84\x04\xcf\x54\x85\x5c\xfb\x36\x17\x75\xa8\xba\x8a\x7e\xb0\x03\x2f\xcc\xe0\xd5\xeb\xfe\xf7\xe2\xbb\x0c\x52\xdf\x8c\x22\xf1\xf8\x4b\xba\x42\x47\xbf\xdd\xf4\xbe\x5e\x44\x0d\x57\xb4\x2f\x39\x38\xc7\x63\xaf\x06\xcd\x89\x2e\x57\x06\x25\xf1\xc5\x8b\x90\x1d\x07\xdf\xdd\x41\xce\xe1\x8a\x28\x4e\x1d\x1a\x13\x55\x21\xf5\x7f\xc7\xf4\x42\x75\x55\x79\x48\x60\x3e\x42\x97\x09\xc1\x1e\xb8\x2c\xfe\x54\x28\xe3\x6f\xe0\x18\x4d\x96\x07\x30\xe9\x4e\xdd\x61\xc9\x4c\xa5\x17\x3e\x04\x92\x83\xfc\x06\x60\x32\x90\xe8\x09\xd2\x24\x8e\xb1\xf1\x3e\x94\x81\x99\xec\x81\x19\x06\x3e\x15\xce\xe1\x17\x79\x0c\x68\x18\x09\x90\xf2\xdd\x97\xc3\x54\x74\xff\xe5\xa4\x93\x3f\x20\xac\x21\xd3\x09\x60\x45\xc7\xdb\x8e\x41\xdb\x25\x32\x06\x97\xbf\xd4\xf6\xa0\x65\xf1\xa7\x02\x7b\xec\x0b\x2e\x65\xba\xc7\xf8\xfd\xd2\x7f\xc5\x3d\x08\x7e\x9c\xce\x04\x7a\x1c\xc4\x71\xec\x38\x8b\x3d\xe4\xf8\xb0\xdf\x43\x8e\xc5\x9f\x8a\xdc\x80\xcb\x44\x05\xc9\xf2\x50\x8e\xee\x8d\xaa\x91\x49\x48\x2f\x7c\x40\x28\x39\xbf\x09\x28\x37\x9e\xfc\x1c\x83\xd2\x87\x3f\x86\xd2\x53\x8b\x3d\x2c\xbd\xfc\x53\xc1\x3c\xca\x92\x52\x4f\x67\x9c\xf8\x59\x44\x94\x1e\x04\x3c\x9f\xd0\x04\x7a\xdb\xc0\xae\x8e\xc1\xe7\x13\xe9\xf1\xa3\x14\xbb\xbb\x09\x0b\xf1\xed\x44\x36\x78\xa3\xcf\x06\xa5\xc1\xe6\x3f\x0b\x59\xa5\x19\xac\x56\xdd\xf8\x33\x4b\xb4\x6c\x66\x61\x05\x36\x7f\xda\x60\x9b\x0e\x78\x83\x4d\xee\x92\xff\x07\x00\x00\xff\xff\x43\x01\x91\xe2\x3a\x2a\x00\x00") +var _schemaGo = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x5a\x5f\x6f\xdc\x36\x12\x7f\x5e\x7d\x8a\x89\x81\x1a\x52\xb0\xd5\xf6\x8a\xa2\xb8\xdb\xdc\x1e\x50\xb4\x29\xea\xeb\xd5\x0d\x9a\xa4\x2f\x41\xe0\xca\x12\xe5\x65\x2c\x91\x5b\x92\xeb\xd8\x75\xf3\xdd\x0f\x33\x43\x4a\x94\x56\xbb\x76\x12\xdb\x2f\x11\x87\xf3\xf7\xc7\xe1\x70\xc8\xcd\x62\x01\xdf\xeb\xcd\x8d\x91\x17\x6b\x07\x5f\x7f\xf5\x8f\x7f\x7d\xb9\x31\xc2\x0a\xe5\xe0\xc7\xa2\x14\xe7\x5a\x5f\xc2\x89\x2a\x73\xf8\xae\x69\x80\x98\x2c\xe0\xbc\xb9\x12\x55\x9e\x2c\x16\xf0\x6a\x2d\x2d\x58\xbd\x35\xa5\x80\x52\x57\x02\xa4\x85\x46\x96\x42\x59\x51\xc1\x56\x55\xc2\x80\x5b\x0b\xf8\x6e\x53\x94\x6b\x01\x5f\xe7\x5f\x85\x59\xa8\xf5\x56\x55\xa8\x42\x2a\x62\xf9\xdf\xc9\xf7\xcf\x4f\x5f\x3e\x87\x5a\x36\x22\xd0\x8c\xd6\x0e\x2a\x69\x44\xe9\xb4\xb9\x01\x5d\x83\x8b\xec\x39\x23\x44\x9e\x24\x9b\xa2\xbc\x2c\x2e\x04\x34\xba\xa8\x92\x44\xb6\x1b\x6d\x1c\xa4\xc9\xec\x48\xa8\x52\x57\x52\x5d\x2c\xde\x59\xad\x8e\x92\xd9\x51\xdd\x3a\xfc\xc7\x88\xba\x11\xa5\x3b\x4a\x92\xd9\xd1\x85\x74\xeb\xed\x79\x5e\xea\x76\x51\xfb\x80\xa5\x2a\xb7\xe7\x85\xd3\x66\x21\x14\xf1\xdf\xc5\xb3\xb0\xe5\x5a\xb4\xc5\x42\x54\x17\xe2\x63\xf8\x6b\x29\x9a\xea\x63\x04\xa4\xaa\xc4\xf5\x51\x92\x25\x08\xdb\x4b\xa2\x81\x11\x7e\xc1\x2c\x14\x0a\x84\x72\xb9\x9f\x70\xeb\xc2\xc1\xfb\xc2\x12\x2e\xa2\x82\xda\xe8\x16\x0a\x28\x75\xbb\x69\x24\x2e\x8e\x15\x06\x3c\x76\x79\xe2\x6e\x36\x22\xa8\xb4\xce\x6c\x4b\x07\xb7\xc9\xec\xb4\x68\x05\x00\x20\x45\xaa\x0b\xa0\xbf\x3f\x10\xcd\xe5\x91\x2a\x5a\x31\xd7\xad\x74\xa2\xdd\xb8\x9b\xa3\x3f\x92\xd9\xf7\x5a\xd5\xf2\x02\xc8\x87\xf0\xed\x99\x4b\x1a\x0e\xd9\x9f\x57\x17\xc2\x02\xc0\x9b\xb7\x4f\xf1\x33\xd6\x8d\x40\xda\x21\xf7\x8f\x88\x95\x25\x6e\xfa\x8c\xb8\x09\xc6\x11\xfb\x09\x22\x25\x2c\xb2\xd3\x67\xc4\x2e\x79\x6a\xc8\xff\x93\xd6\x97\xde\x99\x17\xda\x4a\x27\xb5\x0a\xfc\x6b\x9c\x1a\x72\xbf\xd0\x8d\x2c\x6f\x00\xce\xb5\x6e\x00\x06\xb0\x6c\x68\x6a\xc0\xfe\x81\x96\xab\x53\x5b\x09\x5b\x1a\x79\x2e\x2c\x14\x40\xae\xc3\x26\x4c\xf9\xac\xe7\xd5\xf6\x6b\xd2\xc9\xf5\xab\xd2\x45\x04\x20\x95\x03\x58\x2c\x80\x31\xa1\xd0\x82\x16\xd6\xdd\x48\xeb\xf2\x64\xf6\x8b\xbc\x16\xd5\x89\x42\x11\x72\x7a\xb1\x80\x13\x55\xc9\xb2\x70\xc2\x82\xac\x23\x01\xcc\x98\x16\xb9\xbf\x94\x8a\x05\xa5\x3a\xf1\x7a\xd9\x16\x91\x86\xb6\x5a\x22\xb1\x2d\x0e\x97\x1d\xda\x4d\x4e\xa6\x7f\x42\x6e\xb2\xe0\x6e\x6a\xf2\x5f\x9c\xa0\xd1\xdf\xde\x5c\x3d\x51\xb5\xee\xd9\x9e\x52\xe8\xf9\xab\x9b\x8d\x88\x27\xbc\x34\x9a\x1f\x4a\xbf\x2a\x62\x53\x87\x6d\xbb\x62\x94\xf7\x2f\xe5\x5f\x91\xe3\x4f\xa5\x72\xdf\x7e\xb3\x4f\xd8\xca\xbf\x46\xa6\x9f\xab\x6d\x6b\x3b\xb6\x37\x6f\x27\x8d\x87\x6d\x84\xbc\x43\xf1\xd7\x4a\xfe\xb9\xed\xcc\xc7\xf9\xbb\x2b\xbe\x25\xde\xa1\xfc\xa9\x6c\x9a\xe2\xbc\x11\xf7\x91\x57\x9e\x77\xa8\xe1\xd7\x0d\x66\x73\xd1\xdc\x47\x83\xf6\xbc\x43\x0d\x3f\x88\xba\xd8\x36\xee\x5e\x31\x54\xcc\x3b\xa9\xe0\xf7\xa2\x41\x28\xa4\x72\xc2\x60\xd9\xbd\xfd\xb0\x5f\xc1\xd9\x15\x32\x8f\xb0\xdc\x54\x85\x13\xc1\x9b\x3b\xb0\x24\xde\xb3\x49\x77\x4e\xda\x76\xeb\x3a\x50\x0f\xeb\x91\x81\x77\xa8\xe2\xf7\xa2\x91\x15\x9e\x16\x94\x1a\xb4\x51\xf7\xaa\xb8\xea\x78\x47\x79\xe9\xb4\x29\x2e\xc4\xcf\xe2\x06\xee\x4c\x6a\xcb\xbc\x67\x97\xe2\x66\x5c\x19\x7d\xb5\xa2\xbf\xa7\xc3\xe1\x48\x49\x28\x7b\x23\x37\x84\x42\xf2\xd5\x7d\xd0\xb0\x81\x77\xa4\x82\xea\x27\xee\x66\xe4\x6d\x8b\xcd\x1b\x8e\xe6\xed\xc4\x31\xc6\xb5\xf6\x6c\x77\x8f\x7f\xa7\x94\x76\x05\xfa\x67\x87\x4a\xe2\x7c\xf1\x4a\x8a\x9e\x77\xa2\xf2\xd3\xe9\xb6\x5b\x09\x89\xfc\x09\x85\x90\xe4\x26\xeb\xe0\xce\x9a\xed\x2d\x7f\x01\x9b\x03\x42\x07\xab\xde\x5e\xa1\x71\xb1\xfb\x4d\xd4\x53\x3d\x44\x2c\x63\x44\x7d\xb6\xeb\xe1\x6f\xa2\x0e\x7c\x7d\x7b\xb0\x23\xb8\xb7\xb8\xed\xe4\xcd\x81\x9a\x76\xa2\xae\x84\xb1\xe2\x90\x98\x64\x96\xb1\x8b\x7f\x6e\xa5\x11\xd5\x01\x39\xe3\x59\xf6\xee\xb4\xa7\xd8\xea\xe4\x11\xe1\x8e\x0d\xc6\x19\xc5\xe7\xf1\x6e\x4a\x31\xfd\x13\x72\x8a\x05\xfb\xa4\x9a\x42\xf2\x00\x82\xa1\x95\x8b\x4f\xa4\xbb\x5b\xb9\x09\xee\xa9\x56\x2e\x02\xa7\x4b\xa1\x7b\xa1\x74\x2a\xde\x53\xe6\x94\x46\x50\x9b\x53\xa8\x80\x08\x3a\xc5\xb0\xd0\x17\x77\x64\x1b\xa7\x4d\x9e\xd4\x5b\x55\x06\xc9\x54\x54\x7e\x81\x7e\xe8\x38\x32\x9f\x8e\xb7\xc9\x4c\x09\x58\xae\xe0\x18\x87\xb7\xc9\x0c\xb7\xc7\x32\x2c\xbf\xa8\xf2\x57\xc5\xc5\x1c\xa9\x37\x1b\xb1\x8c\xa8\xb8\xab\x92\x19\xed\xda\x88\x8c\x43\x24\x33\xee\xcb\x40\xe6\x21\x4e\xf8\x1c\x5d\xfa\x09\x3f\xc4\x99\x90\x85\x4b\x9e\x09\x43\x9e\xaa\x3b\x3b\x34\x55\x07\x3b\x3d\xa6\x4b\x9c\xe9\x87\xf3\x64\xf6\x21\x99\xc9\x1a\x8c\xa8\x31\x3a\x16\x7b\x46\xc3\x27\x2b\x50\xb2\xc1\xc8\x67\x4a\x20\x19\x56\x1d\x52\x46\xd4\x19\xd3\xa3\xe5\x5a\x01\xf3\x45\x34\x52\x6f\x84\xdb\x1a\x05\x4a\xf4\x0b\xc5\xdd\xdd\xee\x4a\x71\x4f\x4a\x4b\xc5\x9f\x53\x6b\x45\xc2\x69\x5d\x85\x3e\x2e\x5e\xad\x94\xaf\x0b\x73\x10\xc6\xe0\xf8\x96\xa2\x13\xc6\x60\x74\x75\x95\x3f\x37\x26\xcd\x9e\x11\x21\x8a\x2f\x78\x28\x9b\x39\xd4\xad\x43\x2e\x6d\xea\x94\xf3\x13\xbe\xf8\x73\x09\x5f\x5c\x1d\xcd\x51\x9e\x10\x45\xf1\x8c\x42\xb3\x84\xda\x31\xd9\xbc\x1d\xad\x33\x40\x27\x40\x2b\x5a\xeb\xe1\x0c\x52\xe6\xa3\x44\xe2\x19\x9f\x4b\xd4\xfb\x2d\xe3\x09\xa2\x8c\x13\x87\xa7\xfa\xdc\x09\x3d\xdb\xb2\xf7\x21\x74\x66\xc9\xac\xeb\xc7\xfa\xd9\x40\xc1\x59\xdf\xdd\x2c\x7b\xbd\xa1\xdf\x61\xb4\xc8\x76\xdc\x07\x2d\xc9\xf6\xa0\x33\xea\x39\xbb\x4e\x67\xd9\xc5\xdc\xf5\x33\xa3\xac\xe4\xe9\x41\x62\x46\x5d\x0e\xcd\x37\x42\xa5\x75\x95\xf7\xd4\x8c\x94\x84\x9e\xa0\xb3\xd1\x51\x68\xba\xeb\x0d\x3a\x1b\x1d\x05\xe7\xa3\x63\x7f\x49\xe7\xfe\xa5\x48\xa7\x0f\xff\x8c\xf7\x4a\xad\x0d\x9c\xcd\xa1\x70\xb8\xf0\xa6\x50\x58\x59\xaa\x3c\xee\x1e\x30\x0f\x6c\x1d\x93\xde\x14\x8e\xf2\x20\xcd\xde\xc2\x0a\x0a\x17\x36\x9d\xad\x29\x09\x60\x75\x77\x26\xb6\xd2\x5a\xac\x85\x54\xbe\x25\x0a\xa1\x23\x21\x3f\x8f\xe6\xa8\x0b\x4d\x64\x9d\x6e\xbc\x76\x2c\x57\x40\xf7\x0d\xc4\x0d\xef\x21\xd9\x33\xa6\x3f\x59\xc1\x57\xc1\x4f\xba\x9f\xac\xe0\x18\x27\x48\x18\x0f\x1c\xbe\x21\xfa\xf6\x15\xa8\x19\x86\xb2\x50\x70\x2e\x80\x5e\x59\x44\x05\x4e\x13\xcf\x85\x50\xc2\x14\xb4\x3f\x51\xf2\x47\x6d\x40\x5c\x17\xed\xa6\x11\x73\x50\xda\xe1\xa5\x77\xab\x4a\x6a\x0a\x1b\x79\x29\xc0\xc9\x56\xe4\xa7\xfa\x7d\x4e\x5e\x9e\xcd\xc3\xde\xc4\x0a\x9f\xff\x52\x18\xbb\x2e\x9a\xb4\xcf\x3b\xbf\x57\x23\x84\x6c\x9d\x0f\x1a\xfa\x55\x94\xa5\x71\xb9\xb1\xf5\x1c\x65\xfa\x9a\xc3\x87\xde\x6e\xcd\xe1\x9b\x2d\xd5\x1c\xfe\x9c\xaa\x39\x24\x9c\xca\xea\x1a\x6f\x70\x95\xb8\x1e\x1e\x11\xac\xfa\xb6\xb3\x7d\x4c\x04\xf4\x96\x8e\x4a\xbf\x9d\x64\x75\x4d\x5d\x20\xed\x60\x3e\x15\x97\xdd\x04\x8f\xc7\x7b\x1b\x67\xfa\x9d\x1d\x6f\x18\x9c\x19\xd5\x71\x8e\xd4\x63\xe8\xdf\x76\x78\xb5\x68\xa5\xa2\xb7\xa2\x2e\xad\xf1\x4b\x43\x01\xff\x7d\xf9\xeb\x29\x0a\x53\x2f\xe1\x17\xba\x12\xbc\xd0\xc4\x82\x0a\xbc\xb0\x3e\x7f\x27\x4a\xe7\xff\xf1\x08\x0d\x8c\xa6\x36\xd8\xc6\x16\xc5\x5b\xca\x20\x3d\x87\x37\x6f\xcf\x6f\x1c\xd7\xcf\xa8\x40\x5b\xaa\xa1\x2c\x8b\x98\xf1\x63\xd2\x32\xbc\x8b\xf0\x30\xcd\xe2\x73\x54\x2a\x7e\x25\x4c\xfd\xdb\x1e\x1d\xb4\xbf\xd6\xde\x72\x96\xf9\xed\xd6\x1d\x6f\x3e\xc9\x6c\x8e\x6b\x4e\x0f\x1a\x81\xf5\xde\x67\x81\x0f\xaa\x3b\x0c\xec\xf8\x2c\x18\x9b\xe1\x15\x7d\x78\x3b\xdc\x62\x75\xb6\x8a\x5a\x50\x52\x05\x43\x9d\x23\x0f\x61\xcb\x57\x3b\xd1\x17\x3b\xb2\xce\x1b\x91\x93\x19\x2b\xda\x66\x23\x54\x95\x7a\xc2\xbc\xef\xa7\xa2\x5d\x92\x66\x99\x87\xc9\xbf\xc7\xc5\x01\xf8\xe7\xbb\xc7\x0c\x01\xb7\x6e\x17\x84\xf7\xc1\x87\x11\x1e\x0f\xa3\x40\x4e\x82\x93\xf1\xd6\x9f\x8c\x66\xb4\xe8\xf4\xb0\xf8\xf8\xb9\xc5\x2f\x92\x0f\x6f\xc7\x0b\x0e\x8a\xb1\xcd\x7c\x65\x79\xad\xda\x41\x6d\xe1\x02\x61\xf9\x18\x90\x57\x42\xc1\xf9\xb6\xae\x85\x01\x2a\x29\xbe\xba\x86\xc7\x4d\x2a\x13\x23\x0d\xe9\xf9\xb6\xf6\x35\x01\x3b\x37\x26\xce\xf7\x55\x86\x01\x0c\xe4\x61\xa7\x0e\x15\xcd\xc1\x1e\x06\x42\x18\x13\x27\x44\xdd\xa7\x83\xf5\xd5\x97\x44\xa2\x76\x31\xf7\x07\xa0\x9d\x68\x19\x77\x55\xa3\xee\xe8\xf8\x89\x4f\x9f\xae\xea\xd0\x97\xf5\xef\xa7\x4e\x7b\x74\xfc\xdd\x24\x2e\x97\x1e\xb0\xd4\x82\x87\x25\x83\x71\xe9\x1a\xd7\x57\x82\x0d\x7d\x23\xed\x83\xfd\x35\xa8\x78\x07\x76\x57\x0c\x91\x9c\x43\x1b\x6d\x19\x76\x99\x2e\x03\x78\xc1\xa7\xce\x62\xba\x06\xb7\xd7\x5d\xfd\x4d\x66\x33\x7f\xc5\x8b\xbd\xf1\x85\xb1\xbd\xce\x7a\xb8\x27\x90\x1d\xb6\x3f\x68\xbd\xcb\x5b\x15\x65\x2d\xfa\x4b\x0e\xbf\x1b\xac\x69\xdd\xaf\xe8\x0c\x5b\x01\x6f\xbf\xbf\x3e\x0c\x77\x33\xb2\x4d\xb8\xf2\xb1\xbe\x90\x33\xd8\xa2\x74\x2f\x61\x2b\x38\x0e\xdf\xac\x91\xca\x89\xef\x08\xde\xcd\x89\xe4\x5f\xeb\x89\xe8\x0c\x9f\xf5\xb3\xe8\x29\x7e\x09\x72\xde\x2b\x0f\xc9\x1a\x95\x2b\xdf\x3c\x80\xad\x03\x20\xfb\x0e\x89\x87\x06\x7d\xdf\xe1\xf0\x49\xa7\x03\x69\x3d\x74\x3e\x3c\x82\xf7\x7b\xcf\x85\xcf\x39\x18\xc8\x00\xff\x90\x14\x87\xc1\x87\xc3\x83\xe7\x7d\xef\x3f\x99\x0c\xde\xf3\x6f\x5c\x91\xef\x3f\xb1\x43\x0f\x98\x8f\xd9\xb8\xea\x0d\x4b\x9e\x4f\x54\xae\x79\x7c\x57\xf9\x84\x9a\x37\xe8\xa3\xf6\x16\xbd\xfd\x75\xe6\xa3\xcb\xde\x74\x15\xb9\x5f\x11\xd9\xbf\xac\xdd\x19\xb1\xb7\x3c\x04\x6c\x89\xe7\xae\x5d\xbe\x83\xf9\x24\x76\x71\x3b\xb2\x17\xba\x7d\x89\xfa\x91\xc0\x4d\xa5\xe1\x7d\xb3\xb0\x4b\x42\x4e\xac\x2e\x01\xeb\xa2\xe1\x67\xaf\x0f\xf7\x0e\x79\xd0\x1a\xed\x8d\xd9\xff\x6e\x1b\x07\x3d\xec\xa9\xee\x11\xb5\xcd\xfd\x0f\xc3\x2b\x60\x75\x9e\x77\xda\xcd\x1a\xf8\x69\x2a\x83\xbe\xab\xe8\xfd\x91\x35\x3c\xe9\x2e\xb6\xf0\xf7\xdf\x38\x3a\x51\xb5\xce\x4f\xb7\xad\x30\xb2\x4c\xb3\x51\x3f\x43\x1e\xa8\x39\xe8\x4b\x6e\x55\xe2\x3b\x71\x9e\xd6\x8d\x2e\xdc\xb7\xdf\x70\x14\x4f\xf4\x65\x2c\x1c\xd7\x97\xad\x12\xd7\x1b\x51\x3a\x51\x8d\x2e\xfb\xf4\xce\xd0\x3d\x31\x2c\xf9\x8d\x21\x7e\x62\xb0\xef\xa5\x2b\xd7\xe0\xd8\x3a\xb9\x8a\xe7\xff\x33\xb4\x54\x16\x56\x80\x83\xff\xac\x20\xfe\xa1\xd5\xfd\x13\x8e\x8f\xc1\xc1\xbf\x47\xe4\x6f\xbf\x59\x62\x25\x1b\xdf\xea\xf9\xe1\x42\x65\xd3\xea\x5e\xcb\x69\x7d\xaf\xe5\x5e\x85\xdb\x5e\xe3\x54\xc1\xea\x2b\x06\xbc\x37\xc5\xc6\xc6\x3f\xcd\x7b\x7a\xa1\x2a\xee\x83\x02\xa1\x15\x6e\xad\x2b\x78\x2f\xdd\x1a\x8c\x28\xf5\x15\x37\xbf\x42\xd9\xad\x11\xa0\x34\x6c\x0a\x25\x4b\x0b\x52\x81\xef\x54\xa5\xba\xf0\x65\x2e\xaa\x50\x75\x15\xfd\x2a\x09\x9e\x98\xc1\x9b\xb7\xfd\x2f\xe8\x1f\x32\x48\x7d\x31\x8a\xc8\xe3\x9b\x74\x25\xb0\xfd\x46\xf5\x3e\x5f\x64\x0d\x57\xb4\x2f\xd9\x39\xec\x63\xaf\x06\xc5\x89\x1e\x57\x06\x29\xf1\xc5\xab\x10\x1d\x3b\xdf\xbd\x7d\xce\xe1\x8a\x5a\x9c\x3a\x14\x26\xca\x42\xaa\xff\xd8\xe9\x85\xec\xaa\xf2\x10\xc0\x7c\x84\x2e\x37\x04\x3b\xe0\x32\xf9\x73\xa1\x8c\xef\xc0\x31\x9a\x4c\x0f\x60\xd2\x5b\x3e\x62\xc9\x9d\x4a\x4f\x7c\x0c\x24\x07\xf1\x0d\xc0\x64\x20\x85\x6f\x90\x26\x71\x8c\x85\x77\xa1\x0c\x9d\xc9\x0e\x98\x61\xe2\x73\xe1\x1c\xde\xc8\x63\x40\xc3\x4c\x80\x94\xdf\xbe\x10\x53\xd9\xfd\x27\x9c\x8e\xfe\x88\xb0\x86\x48\x27\x80\x95\x5d\xdf\x76\x08\xda\x2e\x90\x31\xb8\x7c\x53\xdb\x81\x96\xc9\x9f\x0b\xec\xa1\x1b\x5c\xca\xed\x1e\xe3\xf7\x4b\x7f\x8b\x7b\x14\xfc\x38\x9c\x09\xf4\xd8\x89\xc3\xd8\x71\x14\x3b\xc8\xf1\x61\xbf\x83\x1c\x93\x3f\x17\xb9\x41\x2f\x13\x25\x24\xd3\x43\x3a\xe2\x88\xb2\x91\x9b\x90\x9e\xf8\x88\x50\x72\x7c\x13\x50\xae\x7d\xf3\x73\x08\x4a\xef\xfe\x18\x4a\xdf\x5a\xec\x60\xe9\xe9\x9f\x0b\xe6\xc1\x2e\x29\xf5\xed\x0c\x92\x5f\x44\x8d\xd2\xa3\x80\xe7\x03\x9a\x40\x6f\x13\xba\xab\x43\xf0\xf9\x40\x7a\xfc\x28\xc4\xee\x6d\xc2\x41\xfc\x3a\x91\x0d\x46\x74\x6d\xd0\x06\x5c\xfe\xb3\x54\x55\x9a\xc1\x6a\xd5\xcd\xbf\x70\xd4\x96\xcd\x1c\xac\xc0\xe5\xcf\x1b\xd1\xa6\x83\xbe\xc1\x25\x1f\x92\xff\x07\x00\x00\xff\xff\xf4\xc4\xa9\x64\x4c\x2b\x00\x00") func schemaGoBytes() ([]byte, error) { return bindataRead( @@ -113,7 +113,7 @@ func schemaGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "schema.go", size: 10810, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "schema.go", size: 11084, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/entc/load/schema.go b/entc/load/schema.go index 0fd2b8bf1..2544cb1af 100644 --- a/entc/load/schema.go +++ b/entc/load/schema.go @@ -35,23 +35,24 @@ type Position struct { // Field represents an ent.Field that was loaded from a complied user package. type Field struct { - Name string `json:"name,omitempty"` - Info *field.TypeInfo `json:"type,omitempty"` - Tag string `json:"tag,omitempty"` - Size *int64 `json:"size,omitempty"` - Enums []string `json:"enums,omitempty"` - Unique bool `json:"unique,omitempty"` - Nillable bool `json:"nillable,omitempty"` - Optional bool `json:"optional,omitempty"` - Default bool `json:"default,omitempty"` - DefaultValue interface{} `json:"default_value,omitempty"` - UpdateDefault bool `json:"update_default,omitempty"` - Immutable bool `json:"immutable,omitempty"` - Validators int `json:"validators,omitempty"` - StorageKey string `json:"storage_key,omitempty"` - Position *Position `json:"position,omitempty"` - Sensitive bool `json:"sensitive,omitempty"` - SchemaType map[string]string `json:"schema_type,omitempty"` + Name string `json:"name,omitempty"` + Info *field.TypeInfo `json:"type,omitempty"` + Tag string `json:"tag,omitempty"` + Size *int64 `json:"size,omitempty"` + Enums []string `json:"enums,omitempty"` + Unique bool `json:"unique,omitempty"` + Nillable bool `json:"nillable,omitempty"` + Optional bool `json:"optional,omitempty"` + Default bool `json:"default,omitempty"` + DefaultValue interface{} `json:"default_value,omitempty"` + UpdateDefault bool `json:"update_default,omitempty"` + Immutable bool `json:"immutable,omitempty"` + Validators int `json:"validators,omitempty"` + StorageKey string `json:"storage_key,omitempty"` + Position *Position `json:"position,omitempty"` + Sensitive bool `json:"sensitive,omitempty"` + SchemaType map[string]string `json:"schema_type,omitempty"` + Annotations map[string]interface{} `json:"annotations,omitempty"` } // Edge represents an ent.Edge that was loaded from a complied user package. @@ -114,6 +115,10 @@ func NewField(fd *field.Descriptor) (*Field, error) { Validators: len(fd.Validators), Sensitive: fd.Sensitive, SchemaType: fd.SchemaType, + Annotations: make(map[string]interface{}), + } + for _, at := range fd.Annotations { + sf.Annotations[at.Name()] = at } if sf.Info == nil { return nil, fmt.Errorf("missing type info for field %q", sf.Name) diff --git a/entc/load/schema_test.go b/entc/load/schema_test.go index 9c8b34d4a..3a571f65d 100644 --- a/entc/load/schema_test.go +++ b/entc/load/schema_test.go @@ -20,6 +20,18 @@ import ( "github.com/stretchr/testify/require" ) +type OrderConfig struct { + FieldName string +} + +func (OrderConfig) Name() string { + return "order_config" +} + +func (o *OrderConfig) MarshalJSON() ([]byte, error) { + return json.Marshal(*o) +} + type User struct { ent.Schema } @@ -28,7 +40,8 @@ func (User) Fields() []ent.Field { return []ent.Field{ field.Int("age"), field.String("name"). - Default("unknown"), + Default("unknown"). + Annotations(&OrderConfig{FieldName: "name"}), field.String("nillable"). Nillable(), field.String("optional"). @@ -81,8 +94,8 @@ func TestMarshalSchema(t *testing.T) { buf, err := MarshalSchema(u) require.NoError(t, err) - schema := &Schema{} - require.NoError(t, json.Unmarshal(buf, schema)) + schema, err := UnmarshalSchema(buf) + require.NoError(t, err) require.Equal(t, "User", schema.Name) require.Len(t, schema.Fields, 8) require.Equal(t, "age", schema.Fields[0].Name) @@ -91,6 +104,9 @@ func TestMarshalSchema(t *testing.T) { require.Equal(t, "name", schema.Fields[1].Name) require.Equal(t, field.TypeString, schema.Fields[1].Info.Type) require.Equal(t, "unknown", schema.Fields[1].DefaultValue) + require.NotEmpty(t, schema.Fields[1].Annotations) + ant := schema.Fields[1].Annotations["order_config"].(map[string]interface{}) + require.Equal(t, ant["FieldName"], "name") require.Equal(t, "nillable", schema.Fields[2].Name) require.Equal(t, field.TypeString, schema.Fields[2].Info.Type) diff --git a/schema/field/field.go b/schema/field/field.go index 42e63c9c5..eeb30a447 100644 --- a/schema/field/field.go +++ b/schema/field/field.go @@ -266,6 +266,19 @@ func (b *stringBuilder) GoType(typ interface{}) *stringBuilder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.String("dir"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *stringBuilder) Annotations(annotations ...Annotation) *stringBuilder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *stringBuilder) Descriptor() *Descriptor { return b.desc @@ -347,6 +360,19 @@ func (b *timeBuilder) GoType(typ interface{}) *timeBuilder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.Time("deleted_at"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *timeBuilder) Annotations(annotations ...Annotation) *timeBuilder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *timeBuilder) Descriptor() *Descriptor { return b.desc @@ -425,6 +451,19 @@ func (b *boolBuilder) GoType(typ interface{}) *boolBuilder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.Bool("deleted"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *boolBuilder) Annotations(annotations ...Annotation) *boolBuilder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *boolBuilder) Descriptor() *Descriptor { return b.desc @@ -462,7 +501,7 @@ func (b *bytesBuilder) Immutable() *bytesBuilder { } // Comment sets the comment of the field. -func (b *bytesBuilder) Comment(c string) *bytesBuilder { +func (b *bytesBuilder) Comment(string) *bytesBuilder { return b } @@ -497,9 +536,17 @@ func (b *bytesBuilder) GoType(typ interface{}) *bytesBuilder { return b } -// Descriptor implements the ent.Field interface by returning its descriptor. -func (b *bytesBuilder) Descriptor() *Descriptor { - return b.desc +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.Bytes("ip"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *bytesBuilder) Annotations(annotations ...Annotation) *bytesBuilder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b } // SchemaType overrides the default database type with a custom @@ -516,6 +563,11 @@ func (b *bytesBuilder) SchemaType(types map[string]string) *bytesBuilder { return b } +// Descriptor implements the ent.Field interface by returning its descriptor. +func (b *bytesBuilder) Descriptor() *Descriptor { + return b.desc +} + // jsonBuilder is the builder for json fields. type jsonBuilder struct { desc *Descriptor @@ -566,6 +618,19 @@ func (b *jsonBuilder) SchemaType(types map[string]string) *jsonBuilder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.JSON("json"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *jsonBuilder) Annotations(annotations ...Annotation) *jsonBuilder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *jsonBuilder) Descriptor() *Descriptor { return b.desc @@ -639,6 +704,19 @@ func (b *enumBuilder) SchemaType(types map[string]string) *enumBuilder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.Enum("enum"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *enumBuilder) Annotations(annotations ...Annotation) *enumBuilder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *enumBuilder) Descriptor() *Descriptor { return b.desc @@ -715,11 +793,32 @@ func (b *uuidBuilder) SchemaType(types map[string]string) *uuidBuilder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.UUID("id", uuid.New()). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *uuidBuilder) Annotations(annotations ...Annotation) *uuidBuilder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *uuidBuilder) Descriptor() *Descriptor { return b.desc } +// Annotation is used to attach arbitrary metadata to the field object in codegen. +// The object must be serializable to JSON raw value (e.g. struct, map or slice). +// Template extensions can retrieve this metadata and use inside their templates. +type Annotation interface { + // Name defines the name of the annotation. + Name() string +} + // A Descriptor for field configuration. type Descriptor struct { Tag string // struct tag. @@ -737,6 +836,7 @@ type Descriptor struct { Enums []string // enum values. Sensitive bool // sensitive info string field. SchemaType map[string]string // override the schema type. + Annotations []Annotation // field annotations. err error } diff --git a/schema/field/gen/numeric.tmpl b/schema/field/gen/numeric.tmpl index 5dadbcd57..5e7703191 100644 --- a/schema/field/gen/numeric.tmpl +++ b/schema/field/gen/numeric.tmpl @@ -174,6 +174,19 @@ func (b *{{ $builder }}) GoType(typ interface{}) *{{ $builder }} { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.{{ $tt }}("{{ $t }}"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *{{ $builder }}) Annotations(annotations ...Annotation) *{{ $builder }} { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *{{ $builder }}) Descriptor() *Descriptor { return b.desc @@ -320,6 +333,19 @@ func (b *{{ $builder }}) GoType(typ interface{}) *{{ $builder }} { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.{{ $tt }}("{{ $t }}"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *{{ $builder }}) Annotations(annotations ...Annotation) *{{ $builder }} { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *{{ $builder }}) Descriptor() *Descriptor { return b.desc diff --git a/schema/field/numeric.go b/schema/field/numeric.go index 464c37d52..3ea971c08 100644 --- a/schema/field/numeric.go +++ b/schema/field/numeric.go @@ -239,6 +239,19 @@ func (b *intBuilder) GoType(typ interface{}) *intBuilder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.Int("int"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *intBuilder) Annotations(annotations ...Annotation) *intBuilder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *intBuilder) Descriptor() *Descriptor { return b.desc @@ -366,6 +379,19 @@ func (b *uintBuilder) GoType(typ interface{}) *uintBuilder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.Uint("uint"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *uintBuilder) Annotations(annotations ...Annotation) *uintBuilder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *uintBuilder) Descriptor() *Descriptor { return b.desc @@ -503,6 +529,19 @@ func (b *int8Builder) GoType(typ interface{}) *int8Builder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.Int8("int8"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *int8Builder) Annotations(annotations ...Annotation) *int8Builder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *int8Builder) Descriptor() *Descriptor { return b.desc @@ -640,6 +679,19 @@ func (b *int16Builder) GoType(typ interface{}) *int16Builder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.Int16("int16"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *int16Builder) Annotations(annotations ...Annotation) *int16Builder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *int16Builder) Descriptor() *Descriptor { return b.desc @@ -777,6 +829,19 @@ func (b *int32Builder) GoType(typ interface{}) *int32Builder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.Int32("int32"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *int32Builder) Annotations(annotations ...Annotation) *int32Builder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *int32Builder) Descriptor() *Descriptor { return b.desc @@ -914,6 +979,19 @@ func (b *int64Builder) GoType(typ interface{}) *int64Builder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.Int64("int64"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *int64Builder) Annotations(annotations ...Annotation) *int64Builder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *int64Builder) Descriptor() *Descriptor { return b.desc @@ -1041,6 +1119,19 @@ func (b *uint8Builder) GoType(typ interface{}) *uint8Builder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.Uint8("uint8"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *uint8Builder) Annotations(annotations ...Annotation) *uint8Builder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *uint8Builder) Descriptor() *Descriptor { return b.desc @@ -1168,6 +1259,19 @@ func (b *uint16Builder) GoType(typ interface{}) *uint16Builder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.Uint16("uint16"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *uint16Builder) Annotations(annotations ...Annotation) *uint16Builder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *uint16Builder) Descriptor() *Descriptor { return b.desc @@ -1295,6 +1399,19 @@ func (b *uint32Builder) GoType(typ interface{}) *uint32Builder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.Uint32("uint32"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *uint32Builder) Annotations(annotations ...Annotation) *uint32Builder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *uint32Builder) Descriptor() *Descriptor { return b.desc @@ -1422,6 +1539,19 @@ func (b *uint64Builder) GoType(typ interface{}) *uint64Builder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.Uint64("uint64"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *uint64Builder) Annotations(annotations ...Annotation) *uint64Builder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *uint64Builder) Descriptor() *Descriptor { return b.desc @@ -1568,6 +1698,19 @@ func (b *float64Builder) GoType(typ interface{}) *float64Builder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.Float64("float64"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *float64Builder) Annotations(annotations ...Annotation) *float64Builder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *float64Builder) Descriptor() *Descriptor { return b.desc @@ -1701,6 +1844,19 @@ func (b *float32Builder) GoType(typ interface{}) *float32Builder { return b } +// Annotations adds a list of annotations to the field object to be used by +// codegen extensions. +// +// field.Float32("float32"). +// Annotations(entgql.Config{ +// Ordered: true, +// }) +// +func (b *float32Builder) Annotations(annotations ...Annotation) *float32Builder { + b.desc.Annotations = append(b.desc.Annotations, annotations...) + return b +} + // Descriptor implements the ent.Field interface by returning its descriptor. func (b *float32Builder) Descriptor() *Descriptor { return b.desc