// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package golang implements Go code generation from compiled VDL packages.
package golang

import (
	"bytes"
	"flag"
	"fmt"
	"go/format"
	"path"
	"strings"
	"text/template"

	"v.io/v23/vdl"
	"v.io/v23/vdlroot/vdltool"
	"v.io/x/ref/lib/vdl/compile"
	"v.io/x/ref/lib/vdl/parse"
	"v.io/x/ref/lib/vdl/vdlutil"
)

type goData struct {
	Package        *compile.Package
	Env            *compile.Env
	Imports        goImports
	createdTargets map[*vdl.Type]bool // set of types whose Targets have already been created
	anonTargets    map[*vdl.Type]int  // tracks unnamed target numbers
	anonReaders    map[*vdl.Type]int  // tracks unnamed decoder numbers
	anonWriters    map[*vdl.Type]int  // tracks unnamed encoder numbers
	typeOfs        map[*vdl.Type]int  // tracks vdl.TypeOf var numbers

	collectImports bool // is this the import collecting pass instead of normal generation
	importMap      importMap
}

var skipGoMethods = flag.Bool("skip-go-methods", false, "Skip go generation of VDL{Read,Write,Zero} methods.")

// testingMode is only set to true in tests, to make testing simpler.
var testingMode = false

// Reference a package in the generator.
// If goData's collectImports mode is set, empty imports will be generated and the set of
// imported  packages will be collected. If collectImports is unset, the list of imported
// packages will be used to return a valid import.
func (data *goData) Pkg(genPkgPath string) string {
	if testingMode {
		return path.Base(genPkgPath) + "."
	}
	if data.collectImports {
		data.importMap.AddPackage(genPkgPath, data.pkgName(genPkgPath))
		return ""
	}
	// Special-case to avoid adding package qualifiers if we're generating code
	// for that package.
	if data.Package.GenPath == genPkgPath {
		return ""
	}
	if local := data.Imports.LookupLocal(genPkgPath); local != "" {
		return local + "."
	}
	data.Env.Errors.Errorf("%s: unknown generated package %q", data.Package.Name, genPkgPath)
	return ""
}

// Reference a package as forced "_" in the generator.
// During the import pass mode, this is used to collect dependencies on wiretypes
// that must have their native conversions registered.
func (data *goData) AddForcedPkg(genPkgPath string) {
	if data.collectImports {
		data.importMap.AddForcedPackage(genPkgPath)
	}
}

func (data *goData) pkgName(genPkgPath string) string {
	// For user imports, ResolvePackageGenPath should resolve to a
	// valid package.
	if pkg := data.Env.ResolvePackageGenPath(genPkgPath); pkg != nil {
		return pkg.Name
	}
	// For system imports, e.g., v.io/v23/vdl just use the basename.
	return path.Base(genPkgPath)
}

func (data *goData) CtxVar(name string) string {
	return name + " *" + data.Pkg("v.io/v23/context") + "T"
}

func (data *goData) OptsVar(name string) string {
	return name + " ..." + data.Pkg("v.io/v23/rpc") + "CallOpt"
}

func (data *goData) SkipGenZeroReadWrite(def *compile.TypeDef) bool {
	switch {
	case *skipGoMethods:
		return true
	case data.Package.Path == "v.io/v23/vdl/vdltest" && strings.HasPrefix(def.Name, "X"):
		// Don't generate VDL{IsZero,Read,Write} for vdltest types that start with
		// X.  This is hard-coded to make it easy to generate test cases.
		return true
	}
	return false
}

func (data *goData) TypeOf(tt *vdl.Type) string {
	if builtin := builtInTypeVars[tt]; builtin != "" {
		return data.Pkg("v.io/v23/vdl") + builtin
	}
	// Keep track of all other types, so we can define the vars later.
	id := data.typeOfs[tt]
	if id == 0 {
		id = len(data.typeOfs) + 1
		data.typeOfs[tt] = id
	}
	return typeOfVarName(tt, id)
}

func typeOfVarName(tt *vdl.Type, id int) string {
	return fmt.Sprintf("__VDLType_%s_%d", tt.Kind(), id)
}

func (data *goData) idToTypeOfs() map[int]*vdl.Type {
	// Create a reverse typeOfs map, so that we dump the vars in order.
	idToType := make(map[int]*vdl.Type, len(data.typeOfs))
	for tt, id := range data.typeOfs {
		idToType[id] = tt
	}
	return idToType
}

func (data *goData) DeclareTypeOfVars() string {
	idToType := data.idToTypeOfs()
	if len(idToType) == 0 {
		return ""
	}
	s := `
// Hold type definitions in package-level variables, for better performance.
var (`
	for id := 1; id <= len(idToType); id++ {
		tt := idToType[id]
		s += fmt.Sprintf(`
	%[1]s *%[2]sType`, typeOfVarName(tt, id), data.Pkg("v.io/v23/vdl"))
	}
	return s + `
)`
}

// DefineTypeOfVars defines the vars holding type definitions.  They are
// declared as unexported package-level vars, and defined separately in the
// __VDLInit func, to ensure they are initialized as early as possible.
func (data *goData) DefineTypeOfVars() string {
	idToType := data.idToTypeOfs()
	if len(idToType) == 0 {
		return ""
	}
	s := `
// Initialize type definitions.`
	for id := 1; id <= len(idToType); id++ {
		// We need to generate a Go expression of type *vdl.Type that represents the
		// type.  Since the rest of our logic can already generate the Go code for
		// any value, we just wrap it in vdl.TypeOf to produce the final result.
		//
		// This may seem like a strange roundtrip, but results in less generator and
		// generated code.
		//
		// There's no need to convert the value to its native representation, since
		// it'll just be converted back in vdl.TypeOf.
		tt := idToType[id]
		typeOf := typeGoWire(data, tt)
		if tt.Kind() != vdl.Optional {
			typeOf = "*" + typeOf
		}
		typeOf = "((" + typeOf + ")(nil))"
		if tt.CanBeOptional() && tt.Kind() != vdl.Optional {
			typeOf += ".Elem()"
		}
		s += fmt.Sprintf(`
	%[1]s = %[2]sTypeOf%[3]s`, typeOfVarName(tt, id), data.Pkg("v.io/v23/vdl"), typeOf)
	}
	return s
}

var builtInTypeVars = map[*vdl.Type]string{
	vdl.AnyType:        "AnyType",
	vdl.BoolType:       "BoolType",
	vdl.ByteType:       "ByteType",
	vdl.Uint16Type:     "Uint16Type",
	vdl.Uint32Type:     "Uint32Type",
	vdl.Uint64Type:     "Uint64Type",
	vdl.Int8Type:       "Int8Type",
	vdl.Int16Type:      "Int16Type",
	vdl.Int32Type:      "Int32Type",
	vdl.Int64Type:      "Int64Type",
	vdl.Float32Type:    "Float32Type",
	vdl.Float64Type:    "Float64Type",
	vdl.StringType:     "StringType",
	vdl.TypeObjectType: "TypeObjectType",
	vdl.ErrorType:      "ErrorType",
}

// Generate takes a populated compile.Package and returns a byte slice
// containing the generated Go source code.
func Generate(pkg *compile.Package, env *compile.Env) []byte {
	validateGoConfig(pkg, env)
	data := &goData{
		Package:        pkg,
		Env:            env,
		collectImports: true,
		importMap:      importMap{},
		createdTargets: make(map[*vdl.Type]bool),
		anonTargets:    make(map[*vdl.Type]int),
		anonReaders:    make(map[*vdl.Type]int),
		anonWriters:    make(map[*vdl.Type]int),
		typeOfs:        make(map[*vdl.Type]int),
	}
	// The implementation uses the template mechanism from text/template and
	// executes the template against the goData instance.
	// First pass: run the templates to collect imports.
	var buf bytes.Buffer
	if err := goTemplate.Execute(&buf, data); err != nil {
		// We shouldn't see an error; it means our template is buggy.
		panic(fmt.Errorf("vdl: couldn't execute template: %v", err))
	}

	// Remove self and built-in package dependencies.  Every package can use
	// itself and the built-in package, so we don't need to record this.
	data.importMap.DeletePackage(pkg)
	data.importMap.DeletePackage(compile.BuiltInPackage)

	// Sort the imports.
	data.Imports = goImports(data.importMap.Sort())

	// Second pass: re-run the templates with the final imports to generate the
	// output file.
	data.collectImports = false
	data.createdTargets = make(map[*vdl.Type]bool)
	data.anonTargets = make(map[*vdl.Type]int)
	data.anonReaders = make(map[*vdl.Type]int)
	data.anonWriters = make(map[*vdl.Type]int)
	data.typeOfs = make(map[*vdl.Type]int)
	buf.Reset()
	if err := goTemplate.Execute(&buf, data); err != nil {
		// We shouldn't see an error; it means our template is buggy.
		panic(fmt.Errorf("vdl: couldn't execute template: %v", err))
	}
	// Use gofmt to format the generated source.
	pretty, err := format.Source(buf.Bytes())
	if err != nil {
		// We shouldn't see an error; it means we generated invalid code.
		fmt.Printf("%s", buf.Bytes())
		panic(fmt.Errorf("vdl: generated invalid Go code: %v", err))
	}
	return pretty
}

// The native types feature is hard to use correctly.  E.g. the package
// containing the wire type must be imported into your Go binary in order for
// the wire<->native registration to work, which is hard to ensure.  E.g.
//
//   package base    // VDL package
//   type Wire int   // has native type native.Int
//
//   package dep     // VDL package
//   import "base"
//   type Foo struct {
//     X base.Wire
//   }
//
// The Go code for package "dep" imports "native", rather than "base":
//
//   package dep     // Go package generated from VDL package
//   import "native"
//   type Foo struct {
//     X native.Int
//   }
//
// Note that when you import the "dep" package in your own code, you always use
// native.Int, rather than base.Wire; the base.Wire representation is only used
// as the wire format, but doesn't appear in generated code.  But in order for
// this to work correctly, the "base" package must imported.  This is tricky.
//
// Restrict the feature to these whitelisted VDL packages for now.
var nativeTypePackageWhitelist = map[string]bool{
	"math": true,
	"time": true,
	"v.io/x/ref/lib/vdl/testdata/nativetest": true,
	"v.io/v23/security":                      true,
	"v.io/v23/vdl":                           true,
	"v.io/v23/vdl/vdltest":                   true,
}

func validateGoConfig(pkg *compile.Package, env *compile.Env) {
	vdlconfig := path.Join(pkg.GenPath, "vdl.config")
	// Validate native type configuration.  Since native types are hard to use, we
	// restrict them to a built-in whitelist of packages for now.
	if len(pkg.Config.Go.WireToNativeTypes) > 0 && !nativeTypePackageWhitelist[pkg.Path] {
		env.Errors.Errorf("%s: Go.WireToNativeTypes is restricted to whitelisted VDL packages", vdlconfig)
	}
	// Make sure each wire type is actually defined in the package, and required
	// fields are all filled in.
	for wire, native := range pkg.Config.Go.WireToNativeTypes {
		baseWire := wire
		if strings.HasPrefix(wire, "*") {
			baseWire = strings.TrimPrefix(wire, "*")
		}
		if def := pkg.ResolveType(baseWire); def == nil {
			env.Errors.Errorf("%s: type %s specified in Go.WireToNativeTypes undefined", vdlconfig, wire)
		}
		if native.Type == "" {
			env.Errors.Errorf("%s: type %s specified in Go.WireToNativeTypes invalid (empty GoType.Type)", vdlconfig, wire)
		}
		for _, imp := range native.Imports {
			if imp.Path == "" || imp.Name == "" {
				env.Errors.Errorf("%s: type %s specified in Go.WireToNativeTypes invalid (empty GoImport.Path or Name)", vdlconfig, wire)
				continue
			}
			importPrefix := imp.Name + "."
			if !strings.Contains(native.Type, importPrefix) &&
				!strings.Contains(native.ToNative, importPrefix) &&
				!strings.Contains(native.FromNative, importPrefix) {
				env.Errors.Errorf("%s: type %s specified in Go.WireToNativeTypes invalid (native type %q doesn't contain import prefix %q)", vdlconfig, wire, native.Type, importPrefix)
			}
		}
		if native.Zero.Mode != vdltool.GoZeroModeUnique && native.Zero.IsZero == "" {
			env.Errors.Errorf("%s: type %s specified in Go.WireToNativeTypes invalid (native type %q must be either Mode:Unique or have a non-empty IsZero)", vdlconfig, wire, native.Type)
		}
	}
}

var goTemplate *template.Template

// The template mechanism is great at high-level formatting and simple
// substitution, but is bad at more complicated logic.  We define some functions
// that we can use in the template so that when things get complicated we back
// off to a regular function.
func init() {
	funcMap := template.FuncMap{
		"firstRuneToExport":     vdlutil.FirstRuneToExportCase,
		"firstRuneToUpper":      vdlutil.FirstRuneToUpper,
		"firstRuneToLower":      vdlutil.FirstRuneToLower,
		"vdlZeroValue":          vdl.ZeroValue,
		"errorName":             errorName,
		"nativeType":            nativeType,
		"noCustomNative":        noCustomNative,
		"typeHasNoCustomNative": typeHasNoCustomNative,
		"typeGo":                typeGo,
		"defineType":            defineType,
		"defineIsZero":          defineIsZero,
		"defineWrite":           defineWrite,
		"defineRead":            defineRead,
		"defineConst":           defineConst,
		"genValueOf":            genValueOf,
		"embedGo":               embedGo,
		"isStreamingMethod":     isStreamingMethod,
		"hasStreamingMethods":   hasStreamingMethods,
		"docBreak":              docBreak,
		"quoteStripDoc":         parse.QuoteStripDoc,
		"argNames":              argNames,
		"argTypes":              argTypes,
		"argNameTypes":          argNameTypes,
		"argParens":             argParens,
		"uniqueName":            uniqueName,
		"uniqueNameImpl":        uniqueNameImpl,
		"serverCallVar":         serverCallVar,
		"serverCallStubVar":     serverCallStubVar,
		"outArgsClient":         outArgsClient,
		"clientStubImpl":        clientStubImpl,
		"clientFinishImpl":      clientFinishImpl,
		"serverStubImpl":        serverStubImpl,
		"reInitStreamValue":     reInitStreamValue,
	}
	goTemplate = template.Must(template.New("genGo").Funcs(funcMap).Parse(genGo))
}

func errorName(def *compile.ErrorDef) string {
	switch {
	case def.Exported:
		return "Err" + def.Name
	default:
		return "err" + vdlutil.FirstRuneToUpper(def.Name)
	}
}

func isStreamingMethod(method *compile.Method) bool {
	return method.InStream != nil || method.OutStream != nil
}

func hasStreamingMethods(methods []*compile.Method) bool {
	for _, method := range methods {
		if isStreamingMethod(method) {
			return true
		}
	}
	return false
}

// docBreak adds a "//\n" break to separate previous comment lines and doc.  If
// doc is empty it returns the empty string.
func docBreak(doc string) string {
	if doc == "" {
		return ""
	}
	return "//\n" + doc
}

// argTypes returns a comma-separated list of each type from args.
func argTypes(first, last string, data *goData, args []*compile.Field) string {
	var result []string
	if first != "" {
		result = append(result, first)
	}
	for _, arg := range args {
		result = append(result, typeGo(data, arg.Type))
	}
	if last != "" {
		result = append(result, last)
	}
	return strings.Join(result, ", ")
}

// argNames returns a comma-separated list of each name from args.  If argPrefix
// is empty, the name specified in args is used; otherwise the name is prefixD,
// where D is the position of the argument.
func argNames(boxPrefix, argPrefix, first, second, last string, args []*compile.Field) string {
	var result []string
	if first != "" {
		result = append(result, first)
	}
	if second != "" {
		result = append(result, second)
	}
	for ix, arg := range args {
		name := arg.Name
		if argPrefix != "" {
			name = fmt.Sprintf("%s%d", argPrefix, ix)
		}
		if arg.Type == vdl.ErrorType {
			// TODO(toddw): Also need to box user-defined external interfaces.  Or can
			// we remove this special-case now?
			name = boxPrefix + name
		}
		result = append(result, name)
	}
	if last != "" {
		result = append(result, last)
	}
	return strings.Join(result, ", ")
}

// argNameTypes returns a comma-separated list of "name type" from args.  If
// argPrefix is empty, the name specified in args is used; otherwise the name is
// prefixD, where D is the position of the argument.  If argPrefix is empty and
// no names are specified in args, no names will be output.
func argNameTypes(argPrefix, first, second, last string, data *goData, args []*compile.Field) string {
	noNames := argPrefix == "" && !hasArgNames(args)
	var result []string
	if first != "" {
		result = append(result, maybeStripArgName(first, noNames))
	}
	if second != "" {
		result = append(result, maybeStripArgName(second, noNames))
	}
	for ax, arg := range args {
		var name string
		switch {
		case noNames:
			break
		case argPrefix == "":
			name = arg.Name + " "
		default:
			name = fmt.Sprintf("%s%d ", argPrefix, ax)
		}
		result = append(result, name+typeGo(data, arg.Type))
	}
	if last != "" {
		result = append(result, maybeStripArgName(last, noNames))
	}
	return strings.Join(result, ", ")
}

func hasArgNames(args []*compile.Field) bool {
	// VDL guarantees that either all args are named, or none of them are.
	return len(args) > 0 && args[0].Name != ""
}

// maybeStripArgName strips away the first space-terminated token from arg, only
// if strip is true.
func maybeStripArgName(arg string, strip bool) string {
	if index := strings.Index(arg, " "); index != -1 && strip {
		return arg[index+1:]
	}
	return arg
}

// argParens takes a list of 0 or more arguments, and adds parens only when
// necessary; if args contains any commas or spaces, we must add parens.
func argParens(argList string) string {
	if strings.IndexAny(argList, ", ") > -1 {
		return "(" + argList + ")"
	}
	return argList
}

// uniqueName returns a unique name based on the interface, method and suffix.
func uniqueName(iface *compile.Interface, method *compile.Method, suffix string) string {
	return iface.Name + method.Name + suffix
}

// uniqueNameImpl returns uniqueName with an "impl" prefix.
func uniqueNameImpl(iface *compile.Interface, method *compile.Method, suffix string) string {
	return "impl" + uniqueName(iface, method, suffix)
}

// The first arg of every server method is a context; the type is either a typed
// context for streams, or rpc.ServerCall for non-streams.
func serverCallVar(name string, data *goData, iface *compile.Interface, method *compile.Method) string {
	if isStreamingMethod(method) {
		return name + " " + uniqueName(iface, method, "ServerCall")
	}
	return name + " " + data.Pkg("v.io/v23/rpc") + "ServerCall"
}

// The first arg of every server stub method is a context; the type is either a
// typed context stub for streams, or rpc.ServerCall for non-streams.
func serverCallStubVar(name string, data *goData, iface *compile.Interface, method *compile.Method) string {
	if isStreamingMethod(method) {
		return name + " *" + uniqueName(iface, method, "ServerCallStub")
	}
	return name + " " + data.Pkg("v.io/v23/rpc") + "ServerCall"
}

// outArgsClient returns the out args of an interface method on the client,
// wrapped in parens if necessary.  The client side always returns a final
// error, in addition to the regular out-args.
func outArgsClient(argPrefix string, errName string, data *goData, iface *compile.Interface, method *compile.Method) string {
	first, args := "", method.OutArgs
	if isStreamingMethod(method) {
		first, args = "ocall "+uniqueName(iface, method, "ClientCall"), nil
	}
	return argParens(argNameTypes(argPrefix, first, "", errName+" error", data, args))
}

// clientStubImpl returns the interface method client stub implementation.
func clientStubImpl(data *goData, iface *compile.Interface, method *compile.Method) string {
	var buf bytes.Buffer
	inargs := "nil"
	if len(method.InArgs) > 0 {
		inargs = "[]interface{}{" + argNames("&", "i", "", "", "", method.InArgs) + "}"
	}
	switch {
	case isStreamingMethod(method):
		fmt.Fprint(&buf, "\tvar call "+data.Pkg("v.io/v23/rpc")+"ClientCall\n")
		fmt.Fprintf(&buf, "\tif call, err = "+data.Pkg("v.io/v23")+"GetClient(ctx).StartCall(ctx, c.name, %q, %s, opts...); err != nil {\n\t\treturn\n\t}\n", method.Name, inargs)
		fmt.Fprintf(&buf, "ocall = &%s{ClientCall: call}\n", uniqueNameImpl(iface, method, "ClientCall"))
	default:
		outargs := "nil"
		if len(method.OutArgs) > 0 {
			outargs = "[]interface{}{" + argNames("", "&o", "", "", "", method.OutArgs) + "}"
		}
		fmt.Fprintf(&buf, "\terr = "+data.Pkg("v.io/v23")+"GetClient(ctx).Call(ctx, c.name, %q, %s, %s, opts...)\n", method.Name, inargs, outargs)
	}
	fmt.Fprint(&buf, "\treturn")
	return buf.String() // the caller writes the trailing newline
}

// clientFinishImpl returns the client finish implementation for method.
func clientFinishImpl(varname string, method *compile.Method) string {
	outargs := argNames("", "&o", "", "", "", method.OutArgs)
	return fmt.Sprintf("\terr = %s.Finish(%s)", varname, outargs)
}

// serverStubImpl returns the interface method server stub implementation.
func serverStubImpl(data *goData, iface *compile.Interface, method *compile.Method) string {
	var buf bytes.Buffer
	inargs := argNames("", "i", "ctx", "call", "", method.InArgs)
	fmt.Fprintf(&buf, "\treturn s.impl.%s(%s)", method.Name, inargs)
	return buf.String() // the caller writes the trailing newline
}

func reInitStreamValue(data *goData, t *vdl.Type, name string) string {
	switch t.Kind() {
	case vdl.Struct:
		return name + " = " + typeGo(data, t) + "{}\n"
	case vdl.Any:
		return name + " = nil\n"
	}
	return ""
}

// The template that we execute against a goData instance to generate our
// code.  Most of this is fairly straightforward substitution and ranges; more
// complicated logic is delegated to the helper functions above.
//
// We try to generate code that has somewhat reasonable formatting, and leave
// the fine-tuning to the go/format package.  Note that go/format won't fix
// some instances of spurious newlines, so we try to keep it reasonable.
const genGo = `
{{$data := .}}
{{$pkg := $data.Package}}
{{$pkg.FileDoc}}

// This file was auto-generated by the vanadium vdl tool.
// Package: {{$pkg.Name}}

{{$pkg.Doc}}package {{$pkg.Name}}

{{if $data.Imports}}
import (
	{{range $imp := $data.Imports}}
	{{if $imp.Name}}{{$imp.Name}} {{end}}"{{$imp.Path}}"{{end}}
){{end}}

var _ = __VDLInit() // Must be first; see __VDLInit comments for details.

{{if $pkg.TypeDefs}}
//////////////////////////////////////////////////
// Type definitions
{{range $tdef := $pkg.TypeDefs}}
{{defineType $data $tdef}}
{{if not ($data.SkipGenZeroReadWrite $tdef)}}
{{defineIsZero $data $tdef}}
{{defineWrite $data $tdef}}
{{defineRead $data $tdef}}
{{end}}
{{end}}

{{if $pkg.Config.Go.WireToNativeTypes}}
// Type-check native conversion functions.
var (
{{range $wire, $native := $pkg.Config.Go.WireToNativeTypes}}{{if noCustomNative $native}}{{$nat := nativeType $data $native $pkg}}
	_ func({{$wire}}, *{{$nat}}) error = {{$wire}}ToNative
	_ func(*{{$wire}}, {{$nat}}) error = {{$wire}}FromNative{{end}}{{end}}
)
{{end}}
{{end}}

{{if $pkg.ConstDefs}}
//////////////////////////////////////////////////
// Const definitions
{{range $cdef := $pkg.ConstDefs}}
{{defineConst $data $cdef}}{{end}}
{{end}}

{{if $pkg.ErrorDefs}}
//////////////////////////////////////////////////
// Error definitions

var (
{{range $edef := $pkg.ErrorDefs}}
	{{$edef.Doc}}{{errorName $edef}} = {{$data.Pkg "v.io/v23/verror"}}Register("{{$edef.ID}}", {{$data.Pkg "v.io/v23/verror"}}{{$edef.RetryCode}}, "{{$edef.English}}"){{end}}
)

{{range $edef := $pkg.ErrorDefs}}
{{$errName := errorName $edef}}
{{$newErr := print (firstRuneToExport "New" $edef.Exported) (firstRuneToUpper $errName)}}
// {{$newErr}} returns an error with the {{$errName}} ID.
func {{$newErr}}(ctx {{argNameTypes "" (print "*" ($data.Pkg "v.io/v23/context") "T") "" "" $data $edef.Params}}) error {
	return {{$data.Pkg "v.io/v23/verror"}}New({{$errName}}, {{argNames "" "" "ctx" "" "" $edef.Params}})
}
{{end}}
{{end}}

{{if $pkg.Interfaces}}
//////////////////////////////////////////////////
// Interface definitions
{{range $iface := $pkg.Interfaces}}
{{$ifaceStreaming := hasStreamingMethods $iface.AllMethods}}
{{$rpc_ := $data.Pkg "v.io/v23/rpc"}}
// {{$iface.Name}}ClientMethods is the client interface
// containing {{$iface.Name}} methods.
{{docBreak $iface.Doc}}type {{$iface.Name}}ClientMethods interface { {{range $embed := $iface.Embeds}}
	{{$embed.Doc}}{{embedGo $data $embed}}ClientMethods{{$embed.DocSuffix}}{{end}}{{range $method := $iface.Methods}}
	{{$method.Doc}}{{$method.Name}}({{argNameTypes "" ($data.CtxVar "_") "" ($data.OptsVar "_") $data $method.InArgs}}) {{outArgsClient "" "_" $data $iface $method}}{{$method.DocSuffix}}{{end}}
}

// {{$iface.Name}}ClientStub adds universal methods to {{$iface.Name}}ClientMethods.
type {{$iface.Name}}ClientStub interface {
	{{$iface.Name}}ClientMethods
	{{$rpc_}}UniversalServiceMethods
}

// {{$iface.Name}}Client returns a client stub for {{$iface.Name}}.
func {{$iface.Name}}Client(name string) {{$iface.Name}}ClientStub {
	return impl{{$iface.Name}}ClientStub{name{{range $embed := $iface.Embeds}}, {{embedGo $data $embed}}Client(name){{end}} }
}

type impl{{$iface.Name}}ClientStub struct {
	name   string
{{range $embed := $iface.Embeds}}
	{{embedGo $data $embed}}ClientStub{{end}}
}

{{range $method := $iface.Methods}}
func (c impl{{$iface.Name}}ClientStub) {{$method.Name}}({{argNameTypes "i" ($data.CtxVar "ctx") "" ($data.OptsVar "opts") $data $method.InArgs}}) {{outArgsClient "o" "err" $data $iface $method}} {
{{clientStubImpl $data $iface $method}}
}
{{end}}

{{range $method := $iface.Methods}}{{if isStreamingMethod $method}}
{{$clientStream := uniqueName $iface $method "ClientStream"}}
{{$clientCall := uniqueName $iface $method "ClientCall"}}
{{$clientCallImpl := uniqueNameImpl $iface $method "ClientCall"}}
{{$clientRecvImpl := uniqueNameImpl $iface $method "ClientCallRecv"}}
{{$clientSendImpl := uniqueNameImpl $iface $method "ClientCallSend"}}

// {{$clientStream}} is the client stream for {{$iface.Name}}.{{$method.Name}}.
type {{$clientStream}} interface { {{if $method.OutStream}}
	// RecvStream returns the receiver side of the {{$iface.Name}}.{{$method.Name}} client stream.
	RecvStream() interface {
		// Advance stages an item so that it may be retrieved via Value.  Returns
		// true iff there is an item to retrieve.  Advance must be called before
		// Value is called.  May block if an item is not available.
		Advance() bool
		// Value returns the item that was staged by Advance.  May panic if Advance
		// returned false or was not called.  Never blocks.
		Value() {{typeGo $data $method.OutStream}}
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	} {{end}}{{if $method.InStream}}
	// SendStream returns the send side of the {{$iface.Name}}.{{$method.Name}} client stream.
	SendStream() interface {
		// Send places the item onto the output stream.  Returns errors
		// encountered while sending, or if Send is called after Close or
		// the stream has been canceled.  Blocks if there is no buffer
		// space; will unblock when buffer space is available or after
		// the stream has been canceled.
		Send(item {{typeGo $data $method.InStream}}) error
		// Close indicates to the server that no more items will be sent;
		// server Recv calls will receive io.EOF after all sent items.
		// This is an optional call - e.g. a client might call Close if it
		// needs to continue receiving items from the server after it's
		// done sending.  Returns errors encountered while closing, or if
		// Close is called after the stream has been canceled.  Like Send,
		// blocks if there is no buffer space available.
		Close() error
	} {{end}}
}

// {{$clientCall}} represents the call returned from {{$iface.Name}}.{{$method.Name}}.
type {{$clientCall}} interface {
	{{$clientStream}} {{if $method.InStream}}
	// Finish performs the equivalent of SendStream().Close, then blocks until
	// the server is done, and returns the positional return values for the call.{{else}}
	// Finish blocks until the server is done, and returns the positional return
	// values for call.{{end}}
	//
	// Finish returns immediately if the call has been canceled; depending on the
	// timing the output could either be an error signaling cancelation, or the
	// valid positional return values from the server.
	//
	// Calling Finish is mandatory for releasing stream resources, unless the call
	// has been canceled or any of the other methods return an error.  Finish should
	// be called at most once.
	Finish() {{argParens (argNameTypes "" "" "" "_ error" $data $method.OutArgs)}}
}

type {{$clientCallImpl}} struct {
	{{$rpc_}}ClientCall{{if $method.OutStream}}
	valRecv {{typeGo $data $method.OutStream}}
	errRecv error{{end}}
}

{{if $method.OutStream}}func (c *{{$clientCallImpl}}) RecvStream() interface {
	Advance() bool
	Value() {{typeGo $data $method.OutStream}}
	Err() error
} {
	return {{$clientRecvImpl}}{c}
}

type {{$clientRecvImpl}} struct {
	c *{{$clientCallImpl}}
}

func (c {{$clientRecvImpl}}) Advance() bool {
	{{reInitStreamValue $data $method.OutStream "c.c.valRecv"}}c.c.errRecv = c.c.Recv(&c.c.valRecv)
	return c.c.errRecv == nil
}
func (c {{$clientRecvImpl}}) Value() {{typeGo $data $method.OutStream}} {
	return c.c.valRecv
}
func (c {{$clientRecvImpl}}) Err() error {
	if c.c.errRecv == {{$data.Pkg "io"}}EOF {
		return nil
	}
	return c.c.errRecv
}
{{end}}{{if $method.InStream}}func (c *{{$clientCallImpl}}) SendStream() interface {
	Send(item {{typeGo $data $method.InStream}}) error
	Close() error
} {
	return {{$clientSendImpl}}{c}
}

type {{$clientSendImpl}} struct {
	c *{{$clientCallImpl}}
}

func (c {{$clientSendImpl}}) Send(item {{typeGo $data $method.InStream}}) error {
	return c.c.Send(item)
}
func (c {{$clientSendImpl}}) Close() error {
	return c.c.CloseSend()
}
{{end}}func (c *{{$clientCallImpl}}) Finish() {{argParens (argNameTypes "o" "" "" "err error" $data $method.OutArgs)}} {
{{clientFinishImpl "c.ClientCall" $method}}
	return
}
{{end}}
{{end}}

// {{$iface.Name}}ServerMethods is the interface a server writer
// implements for {{$iface.Name}}.
{{docBreak $iface.Doc}}type {{$iface.Name}}ServerMethods interface { {{range $embed := $iface.Embeds}}
	{{$embed.Doc}}{{embedGo $data $embed}}ServerMethods{{$embed.DocSuffix}}{{end}}{{range $method := $iface.Methods}}
	{{$method.Doc}}{{$method.Name}}({{argNameTypes "" ($data.CtxVar "_") (serverCallVar "_" $data $iface $method) "" $data $method.InArgs}}) {{argParens (argNameTypes "" "" "" "_ error" $data $method.OutArgs)}}{{$method.DocSuffix}}{{end}}
}

// {{$iface.Name}}ServerStubMethods is the server interface containing
// {{$iface.Name}} methods, as expected by rpc.Server.{{if $ifaceStreaming}}
// The only difference between this interface and {{$iface.Name}}ServerMethods
// is the streaming methods.{{else}}
// There is no difference between this interface and {{$iface.Name}}ServerMethods
// since there are no streaming methods.{{end}}
type {{$iface.Name}}ServerStubMethods {{if $ifaceStreaming}}interface { {{range $embed := $iface.Embeds}}
	{{$embed.Doc}}{{embedGo $data $embed}}ServerStubMethods{{$embed.DocSuffix}}{{end}}{{range $method := $iface.Methods}}
	{{$method.Doc}}{{$method.Name}}({{argNameTypes "" ($data.CtxVar "_") (serverCallStubVar "_" $data $iface $method) "" $data $method.InArgs}}) {{argParens (argNameTypes "" "" "" "_ error" $data $method.OutArgs)}}{{$method.DocSuffix}}{{end}}
}
{{else}}{{$iface.Name}}ServerMethods
{{end}}

// {{$iface.Name}}ServerStub adds universal methods to {{$iface.Name}}ServerStubMethods.
type {{$iface.Name}}ServerStub interface {
	{{$iface.Name}}ServerStubMethods
	// Describe the {{$iface.Name}} interfaces.
	Describe__() []{{$rpc_}}InterfaceDesc
}

// {{$iface.Name}}Server returns a server stub for {{$iface.Name}}.
// It converts an implementation of {{$iface.Name}}ServerMethods into
// an object that may be used by rpc.Server.
func {{$iface.Name}}Server(impl {{$iface.Name}}ServerMethods) {{$iface.Name}}ServerStub {
	stub := impl{{$iface.Name}}ServerStub{
		impl: impl,{{range $embed := $iface.Embeds}}
		{{$embed.Name}}ServerStub: {{embedGo $data $embed}}Server(impl),{{end}}
	}
	// Initialize GlobState; always check the stub itself first, to handle the
	// case where the user has the Glob method defined in their VDL source.
	if gs := {{$rpc_}}NewGlobState(stub); gs != nil {
		stub.gs = gs
	} else if gs := {{$rpc_}}NewGlobState(impl); gs != nil {
		stub.gs = gs
	}
	return stub
}

type impl{{$iface.Name}}ServerStub struct {
	impl {{$iface.Name}}ServerMethods{{range $embed := $iface.Embeds}}
	{{embedGo $data $embed}}ServerStub{{end}}
	gs *{{$rpc_}}GlobState
}

{{range $method := $iface.Methods}}
func (s impl{{$iface.Name}}ServerStub) {{$method.Name}}({{argNameTypes "i" ($data.CtxVar "ctx") (serverCallStubVar "call" $data $iface $method) "" $data $method.InArgs}}) {{argParens (argTypes "" "error" $data $method.OutArgs)}} {
{{serverStubImpl $data $iface $method}}
}
{{end}}

func (s impl{{$iface.Name}}ServerStub) Globber() *{{$rpc_}}GlobState {
	return s.gs
}

func (s impl{{$iface.Name}}ServerStub) Describe__() []{{$rpc_}}InterfaceDesc {
	return []{{$rpc_}}InterfaceDesc{ {{$iface.Name}}Desc{{range $embed := $iface.TransitiveEmbeds}}, {{embedGo $data $embed}}Desc{{end}} }
}

// {{$iface.Name}}Desc describes the {{$iface.Name}} interface.
var {{$iface.Name}}Desc {{$rpc_}}InterfaceDesc = desc{{$iface.Name}}

// desc{{$iface.Name}} hides the desc to keep godoc clean.
var desc{{$iface.Name}} = {{$rpc_}}InterfaceDesc{ {{if $iface.Name}}
	Name: "{{$iface.Name}}",{{end}}{{if $iface.File.Package.Path}}
	PkgPath: "{{$iface.File.Package.Path}}",{{end}}{{if $iface.Doc}}
	Doc: {{quoteStripDoc $iface.Doc}},{{end}}{{if $iface.Embeds}}
	Embeds: []{{$rpc_}}EmbedDesc{ {{range $embed := $iface.Embeds}}
		{ "{{$embed.Name}}", "{{$embed.File.Package.Path}}", {{quoteStripDoc $embed.Doc}} },{{end}}
	},{{end}}{{if $iface.Methods}}
	Methods: []{{$rpc_}}MethodDesc{ {{range $method := $iface.Methods}}
		{ {{if $method.Name}}
			Name: "{{$method.Name}}",{{end}}{{if $method.Doc}}
			Doc: {{quoteStripDoc $method.Doc}},{{end}}{{if $method.InArgs}}
			InArgs: []{{$rpc_}}ArgDesc{ {{range $arg := $method.InArgs}}
				{ "{{$arg.Name}}", {{quoteStripDoc $arg.Doc}} }, // {{typeGo $data $arg.Type}}{{end}}
			},{{end}}{{if $method.OutArgs}}
			OutArgs: []{{$rpc_}}ArgDesc{ {{range $arg := $method.OutArgs}}
				{ "{{$arg.Name}}", {{quoteStripDoc $arg.Doc}} }, // {{typeGo $data $arg.Type}}{{end}}
			},{{end}}{{if $method.Tags}}
			Tags: []*{{$data.Pkg "v.io/v23/vdl"}}Value{ {{range $tag := $method.Tags}}{{genValueOf $data $tag}} ,{{end}} },{{end}}
		},{{end}}
	},{{end}}
}

{{range $method := $iface.Methods}}
{{if isStreamingMethod $method}}
{{$serverStream := uniqueName $iface $method "ServerStream"}}
{{$serverCall := uniqueName $iface $method "ServerCall"}}
{{$serverCallStub := uniqueName $iface $method "ServerCallStub"}}
{{$serverRecvImpl := uniqueNameImpl $iface $method "ServerCallRecv"}}
{{$serverSendImpl := uniqueNameImpl $iface $method "ServerCallSend"}}

// {{$serverStream}} is the server stream for {{$iface.Name}}.{{$method.Name}}.
type {{$serverStream}} interface { {{if $method.InStream}}
	// RecvStream returns the receiver side of the {{$iface.Name}}.{{$method.Name}} server stream.
	RecvStream() interface {
		// Advance stages an item so that it may be retrieved via Value.  Returns
		// true iff there is an item to retrieve.  Advance must be called before
		// Value is called.  May block if an item is not available.
		Advance() bool
		// Value returns the item that was staged by Advance.  May panic if Advance
		// returned false or was not called.  Never blocks.
		Value() {{typeGo $data $method.InStream}}
		// Err returns any error encountered by Advance.  Never blocks.
		Err() error
	} {{end}}{{if $method.OutStream}}
	// SendStream returns the send side of the {{$iface.Name}}.{{$method.Name}} server stream.
	SendStream() interface {
		// Send places the item onto the output stream.  Returns errors encountered
		// while sending.  Blocks if there is no buffer space; will unblock when
		// buffer space is available.
		Send(item {{typeGo $data $method.OutStream}}) error
	} {{end}}
}

// {{$serverCall}} represents the context passed to {{$iface.Name}}.{{$method.Name}}.
type {{$serverCall}} interface {
	{{$rpc_}}ServerCall
	{{$serverStream}}
}

// {{$serverCallStub}} is a wrapper that converts rpc.StreamServerCall into
// a typesafe stub that implements {{$serverCall}}.
type {{$serverCallStub}} struct {
	{{$rpc_}}StreamServerCall{{if $method.InStream}}
	valRecv {{typeGo $data $method.InStream}}
	errRecv error{{end}}
}

// Init initializes {{$serverCallStub}} from rpc.StreamServerCall.
func (s *{{$serverCallStub}}) Init(call {{$rpc_}}StreamServerCall) {
	s.StreamServerCall = call
}

{{if $method.InStream}}// RecvStream returns the receiver side of the {{$iface.Name}}.{{$method.Name}} server stream.
func (s  *{{$serverCallStub}}) RecvStream() interface {
	Advance() bool
	Value() {{typeGo $data $method.InStream}}
	Err() error
} {
	return {{$serverRecvImpl}}{s}
}

type {{$serverRecvImpl}} struct {
	s *{{$serverCallStub}}
}

func (s {{$serverRecvImpl}}) Advance() bool {
	{{reInitStreamValue $data $method.InStream "s.s.valRecv"}}s.s.errRecv = s.s.Recv(&s.s.valRecv)
	return s.s.errRecv == nil
}
func (s {{$serverRecvImpl}}) Value() {{typeGo $data $method.InStream}} {
	return s.s.valRecv
}
func (s {{$serverRecvImpl}}) Err() error {
	if s.s.errRecv == {{$data.Pkg "io"}}EOF {
		return nil
	}
	return s.s.errRecv
}
{{end}}{{if $method.OutStream}}// SendStream returns the send side of the {{$iface.Name}}.{{$method.Name}} server stream.
func (s *{{$serverCallStub}}) SendStream() interface {
	Send(item {{typeGo $data $method.OutStream}}) error
} {
	return {{$serverSendImpl}}{s}
}

type {{$serverSendImpl}} struct {
	s *{{$serverCallStub}}
}

func (s {{$serverSendImpl}}) Send(item {{typeGo $data $method.OutStream}}) error {
	return s.s.Send(item)
}
{{end}}{{end}}{{end}}{{end}}{{end}}

{{$data.DeclareTypeOfVars}}

var __VDLInitCalled bool

// __VDLInit performs vdl initialization.  It is safe to call multiple times.
// If you have an init ordering issue, just insert the following line verbatim
// into your source files in this package, right after the "package foo" clause:
//
//    var _ = __VDLInit()
//
// The purpose of this function is to ensure that vdl initialization occurs in
// the right order, and very early in the init sequence.  In particular, vdl
// registration and package variable initialization needs to occur before
// functions like vdl.TypeOf will work properly.
//
// This function returns a dummy value, so that it can be used to initialize the
// first var in the file, to take advantage of Go's defined init order.
func __VDLInit() struct{} {
	if __VDLInitCalled {
		return struct{}{}
	}
	__VDLInitCalled = true
{{if $pkg.Config.Go.WireToNativeTypes}}
	// Register native type conversions first, so that vdl.TypeOf works.{{range $wire, $native := $pkg.Config.Go.WireToNativeTypes}}{{if noCustomNative $native}}
	{{$data.Pkg "v.io/v23/vdl"}}RegisterNative({{$wire}}ToNative, {{$wire}}FromNative){{end}}{{end}}
{{end}}
{{if $pkg.TypeDefs}}
	// Register types.{{range $tdef := $pkg.TypeDefs}}{{if typeHasNoCustomNative $data $tdef}}
	{{$data.Pkg "v.io/v23/vdl"}}Register((*{{$tdef.Name}})(nil)){{end}}{{end}}
{{end}}
{{$data.DefineTypeOfVars}}
{{if $pkg.ErrorDefs}}
	// Set error format strings.{{/* TODO(toddw): Don't set "en-US" or "en" again, since it's already set by the original verror.Register call. */}}{{range $edef := $pkg.ErrorDefs}}{{range $lf := $edef.Formats}}
	{{$data.Pkg "v.io/v23/i18n"}}Cat().SetWithBase({{$data.Pkg "v.io/v23/i18n"}}LangID("{{$lf.Lang}}"), {{$data.Pkg "v.io/v23/i18n"}}MsgID({{errorName $edef}}.ID), "{{$lf.Fmt}}"){{end}}{{end}}
{{end}}
	return struct{}{}
}
`
