| // Copyright 2019 CUE Authors |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package gocode |
| |
| import "text/template" |
| |
| // Inputs: |
| // .pkgName the Go package name |
| var headerCode = template.Must(template.New("header").Parse( |
| `// Code generated by gocode.Generate; DO NOT EDIT. |
| |
| package {{.pkgName}} |
| |
| import ( |
| "fmt" |
| |
| "cuelang.org/go/cue" |
| "cuelang.org/go/encoding/gocode/gocodec" |
| _ "cuelang.org/go/pkg" |
| ) |
| |
| `)) |
| |
| // Inputs: |
| // .prefix prefix to all generated variable names |
| // .cueName name of the top-level CUE value |
| // .goType Go type of the receiver or argument |
| // .zero zero value of the Go type; nil indicates no value |
| // .validate name of the validate function; "" means no validate |
| // .complete name of the complete function; "" means no complete |
| var stubCode = template.Must(template.New("type").Parse(` |
| var {{.prefix}}val{{.cueName}} = {{.prefix}}Make("{{.cueName}}", {{.zero}}) |
| |
| {{ $sig := .goType | printf "(x %s)" -}} |
| {{if .validate}} |
| // {{.validate}}{{if .func}}{{.cueName}}{{end}} validates x. |
| func {{if .func}}{{.validate}}{{.cueName}}{{$sig}} |
| {{- else -}}{{$sig}} {{.validate}}(){{end}} error { |
| return {{.prefix}}Codec.Validate({{.prefix}}val{{.cueName}}, x) |
| } |
| {{end}} |
| {{if .complete}} |
| // {{.complete}}{{if .func}}{{.cueName}}{{end}} completes x. |
| func {{if .func}}{{.complete}}{{.cueName}}{{$sig}} |
| {{- else -}}{{$sig}} {{.complete}}(){{end}} error { |
| return {{.prefix}}Codec.Complete({{.prefix}}val{{.cueName}}, x) |
| } |
| {{end}} |
| `)) |
| |
| // Inputs: |
| // .prefix prefix to all generated variable names |
| // .runtime the variable name of a user-supplied runtime, if any |
| // .data bytes obtained from Instance.MarshalBinary |
| var loadCode = template.Must(template.New("load").Parse(` |
| var {{.prefix}}Codec, {{.prefix}}Instance = func() (*gocodec.Codec, *cue.Instance) { |
| var r *cue.Runtime |
| r = {{if .runtime}}{{.runtime}}{{else}}&cue.Runtime{}{{end}} |
| instances, err := r.Unmarshal({{.prefix}}InstanceData) |
| if err != nil { |
| panic(err) |
| } |
| if len(instances) != 1 { |
| panic("expected encoding of exactly one instance") |
| } |
| return gocodec.New(r, nil), instances[0] |
| }() |
| |
| // {{.prefix}}Make is called in the init phase to initialize CUE values for |
| // validation functions. |
| func {{.prefix}}Make(name string, x interface{}) cue.Value { |
| f, err := {{.prefix}}Instance.Value().FieldByName(name, true) |
| if err != nil { |
| panic(fmt.Errorf("could not find type %q in instance", name)) |
| } |
| v := f.Value |
| if x != nil { |
| w, err := {{.prefix}}Codec.ExtractType(x) |
| if err != nil { |
| panic(err) |
| } |
| v = v.Unify(w) |
| } |
| return v |
| } |
| |
| // Data size: {{len .data}} bytes. |
| var {{.prefix}}InstanceData = []byte({{printf "%+q" .data}}) |
| `)) |