go-micro.dev/v5@v5.12.0/cmd/protoc-gen-micro/generator/generator.go (about)

     1  // Go support for Protocol Buffers - Google's data interchange format
     2  //
     3  // Copyright 2010 The Go Authors.  All rights reserved.
     4  // https://google.golang.org/protobuf
     5  //
     6  // Redistribution and use in source and binary forms, with or without
     7  // modification, are permitted provided that the following conditions are
     8  // met:
     9  //
    10  //     * Redistributions of source code must retain the above copyright
    11  // notice, this list of conditions and the following disclaimer.
    12  //     * Redistributions in binary form must reproduce the above
    13  // copyright notice, this list of conditions and the following disclaimer
    14  // in the documentation and/or other materials provided with the
    15  // distribution.
    16  //     * Neither the name of Google Inc. nor the names of its
    17  // contributors may be used to endorse or promote products derived from
    18  // this software without specific prior written permission.
    19  //
    20  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    21  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    22  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    23  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    24  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    25  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    26  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    27  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    28  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    29  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    30  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31  
    32  /*
    33  The code generator for the plugin for the Google protocol buffer compiler.
    34  It generates Go code from the protocol buffer description files read by the
    35  main routine.
    36  */
    37  package generator
    38  
    39  import (
    40  	"bufio"
    41  	"bytes"
    42  	"compress/gzip"
    43  	"crypto/sha256"
    44  	"encoding/hex"
    45  	"fmt"
    46  	"go/ast"
    47  	"go/build"
    48  	"go/parser"
    49  	"go/printer"
    50  	"go/token"
    51  	"log"
    52  	"os"
    53  	"path"
    54  	"sort"
    55  	"strconv"
    56  	"strings"
    57  	"unicode"
    58  	"unicode/utf8"
    59  
    60  	"google.golang.org/protobuf/proto"
    61  	descriptor "google.golang.org/protobuf/types/descriptorpb"
    62  	plugin "google.golang.org/protobuf/types/pluginpb"
    63  )
    64  
    65  // SupportedFeatures used to signaling that code generator supports proto3 optional
    66  // https://github.com/protocolbuffers/protobuf/blob/master/docs/implementing_proto3_presence.md#signaling-that-your-code-generator-supports-proto3-optional
    67  var SupportedFeatures = uint64(plugin.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL)
    68  
    69  // A Plugin provides functionality to add to the output during Go code generation,
    70  // such as to produce RPC stubs.
    71  type Plugin interface {
    72  	// Name identifies the plugin.
    73  	Name() string
    74  	// Init is called once after data structures are built but before
    75  	// code generation begins.
    76  	Init(g *Generator)
    77  	// Generate produces the code generated by the plugin for this file,
    78  	// except for the imports, by calling the generator's methods P, In, and Out.
    79  	Generate(file *FileDescriptor)
    80  	// GenerateImports produces the import declarations for this file.
    81  	// It is called after Generate.
    82  	GenerateImports(file *FileDescriptor, imports map[GoImportPath]GoPackageName)
    83  }
    84  
    85  var plugins []Plugin
    86  
    87  // RegisterPlugin installs a (second-order) plugin to be run when the Go output is generated.
    88  // It is typically called during initialization.
    89  func RegisterPlugin(p Plugin) {
    90  	plugins = append(plugins, p)
    91  }
    92  
    93  // A GoImportPath is the import path of a Go package. e.g., "google.golang.org/genproto/protobuf".
    94  type GoImportPath string
    95  
    96  func (p GoImportPath) String() string { return strconv.Quote(string(p)) }
    97  
    98  // A GoPackageName is the name of a Go package. e.g., "protobuf".
    99  type GoPackageName string
   100  
   101  // Each type we import as a protocol buffer (other than FileDescriptorProto) needs
   102  // a pointer to the FileDescriptorProto that represents it.  These types achieve that
   103  // wrapping by placing each Proto inside a struct with the pointer to its File. The
   104  // structs have the same names as their contents, with "Proto" removed.
   105  // FileDescriptor is used to store the things that it points to.
   106  
   107  // The file and package name method are common to messages and enums.
   108  type common struct {
   109  	file *FileDescriptor // File this object comes from.
   110  }
   111  
   112  // GoImportPath is the import path of the Go package containing the type.
   113  func (c *common) GoImportPath() GoImportPath {
   114  	return c.file.importPath
   115  }
   116  
   117  func (c *common) File() *FileDescriptor { return c.file }
   118  
   119  func fileIsProto3(file *descriptor.FileDescriptorProto) bool {
   120  	return file.GetSyntax() == "proto3"
   121  }
   122  
   123  func (c *common) proto3() bool { return fileIsProto3(c.file.FileDescriptorProto) }
   124  
   125  // Descriptor represents a protocol buffer message.
   126  type Descriptor struct {
   127  	common
   128  	*descriptor.DescriptorProto
   129  	parent   *Descriptor            // The containing message, if any.
   130  	nested   []*Descriptor          // Inner messages, if any.
   131  	enums    []*EnumDescriptor      // Inner enums, if any.
   132  	ext      []*ExtensionDescriptor // Extensions, if any.
   133  	typename []string               // Cached typename vector.
   134  	index    int                    // The index into the container, whether the file or another message.
   135  	path     string                 // The SourceCodeInfo path as comma-separated integers.
   136  	group    bool
   137  }
   138  
   139  // TypeName returns the elements of the dotted type name.
   140  // The package name is not part of this name.
   141  func (d *Descriptor) TypeName() []string {
   142  	if d.typename != nil {
   143  		return d.typename
   144  	}
   145  	n := 0
   146  	for parent := d; parent != nil; parent = parent.parent {
   147  		n++
   148  	}
   149  	s := make([]string, n)
   150  	for parent := d; parent != nil; parent = parent.parent {
   151  		n--
   152  		s[n] = parent.GetName()
   153  	}
   154  	d.typename = s
   155  	return s
   156  }
   157  
   158  // EnumDescriptor describes an enum. If it's at top level, its parent will be nil.
   159  // Otherwise it will be the descriptor of the message in which it is defined.
   160  type EnumDescriptor struct {
   161  	common
   162  	*descriptor.EnumDescriptorProto
   163  	parent   *Descriptor // The containing message, if any.
   164  	typename []string    // Cached typename vector.
   165  	index    int         // The index into the container, whether the file or a message.
   166  	path     string      // The SourceCodeInfo path as comma-separated integers.
   167  }
   168  
   169  // TypeName returns the elements of the dotted type name.
   170  // The package name is not part of this name.
   171  func (e *EnumDescriptor) TypeName() (s []string) {
   172  	if e.typename != nil {
   173  		return e.typename
   174  	}
   175  	name := e.GetName()
   176  	if e.parent == nil {
   177  		s = make([]string, 1)
   178  	} else {
   179  		pname := e.parent.TypeName()
   180  		s = make([]string, len(pname)+1)
   181  		copy(s, pname)
   182  	}
   183  	s[len(s)-1] = name
   184  	e.typename = s
   185  	return s
   186  }
   187  
   188  // Everything but the last element of the full type name, CamelCased.
   189  // The values of type Foo.Bar are call Foo_value1... not Foo_Bar_value1... .
   190  func (e *EnumDescriptor) prefix() string {
   191  	if e.parent == nil {
   192  		// If the enum is not part of a message, the prefix is just the type name.
   193  		return CamelCase(*e.Name) + "_"
   194  	}
   195  	typeName := e.TypeName()
   196  	return CamelCaseSlice(typeName[0:len(typeName)-1]) + "_"
   197  }
   198  
   199  // The integer value of the named constant in this enumerated type.
   200  func (e *EnumDescriptor) integerValueAsString(name string) string {
   201  	for _, c := range e.Value {
   202  		if c.GetName() == name {
   203  			return fmt.Sprint(c.GetNumber())
   204  		}
   205  	}
   206  	log.Fatal("cannot find value for enum constant")
   207  	return ""
   208  }
   209  
   210  // ExtensionDescriptor describes an extension. If it's at top level, its parent will be nil.
   211  // Otherwise it will be the descriptor of the message in which it is defined.
   212  type ExtensionDescriptor struct {
   213  	common
   214  	*descriptor.FieldDescriptorProto
   215  	parent *Descriptor // The containing message, if any.
   216  }
   217  
   218  // TypeName returns the elements of the dotted type name.
   219  // The package name is not part of this name.
   220  func (e *ExtensionDescriptor) TypeName() (s []string) {
   221  	name := e.GetName()
   222  	if e.parent == nil {
   223  		// top-level extension
   224  		s = make([]string, 1)
   225  	} else {
   226  		pname := e.parent.TypeName()
   227  		s = make([]string, len(pname)+1)
   228  		copy(s, pname)
   229  	}
   230  	s[len(s)-1] = name
   231  	return s
   232  }
   233  
   234  // DescName returns the variable name used for the generated descriptor.
   235  func (e *ExtensionDescriptor) DescName() string {
   236  	// The full type name.
   237  	typeName := e.TypeName()
   238  	// Each scope of the extension is individually CamelCased, and all are joined with "_" with an "E_" prefix.
   239  	for i, s := range typeName {
   240  		typeName[i] = CamelCase(s)
   241  	}
   242  	return "E_" + strings.Join(typeName, "_")
   243  }
   244  
   245  // ImportedDescriptor describes a type that has been publicly imported from another file.
   246  type ImportedDescriptor struct {
   247  	common
   248  	o Object
   249  }
   250  
   251  func (id *ImportedDescriptor) TypeName() []string { return id.o.TypeName() }
   252  
   253  // FileDescriptor describes an protocol buffer descriptor file (.proto).
   254  // It includes slices of all the messages and enums defined within it.
   255  // Those slices are constructed by WrapTypes.
   256  type FileDescriptor struct {
   257  	*descriptor.FileDescriptorProto
   258  	desc []*Descriptor          // All the messages defined in this file.
   259  	enum []*EnumDescriptor      // All the enums defined in this file.
   260  	ext  []*ExtensionDescriptor // All the top-level extensions defined in this file.
   261  	imp  []*ImportedDescriptor  // All types defined in files publicly imported by this file.
   262  
   263  	// Comments, stored as a map of path (comma-separated integers) to the comment.
   264  	comments map[string]*descriptor.SourceCodeInfo_Location
   265  
   266  	// The full list of symbols that are exported,
   267  	// as a map from the exported object to its symbols.
   268  	// This is used for supporting public imports.
   269  	exported map[Object][]symbol
   270  
   271  	importPath  GoImportPath  // Import path of this file's package.
   272  	packageName GoPackageName // Name of this file's Go package.
   273  
   274  	proto3 bool // whether to generate proto3 code for this file
   275  }
   276  
   277  // VarName is the variable name we'll use in the generated code to refer
   278  // to the compressed bytes of this descriptor. It is not exported, so
   279  // it is only valid inside the generated package.
   280  func (d *FileDescriptor) VarName() string {
   281  	h := sha256.Sum256([]byte(d.GetName()))
   282  	return fmt.Sprintf("fileDescriptor_%s", hex.EncodeToString(h[:8]))
   283  }
   284  
   285  // goPackageOption interprets the file's go_package option.
   286  // If there is no go_package, it returns ("", "", false).
   287  // If there's a simple name, it returns ("", pkg, true).
   288  // If the option implies an import path, it returns (impPath, pkg, true).
   289  func (d *FileDescriptor) goPackageOption() (impPath GoImportPath, pkg GoPackageName, ok bool) {
   290  	opt := d.GetOptions().GetGoPackage()
   291  	if opt == "" {
   292  		return "", "", false
   293  	}
   294  	// A semicolon-delimited suffix delimits the import path and package name.
   295  	sc := strings.Index(opt, ";")
   296  	if sc >= 0 {
   297  		return GoImportPath(opt[:sc]), cleanPackageName(opt[sc+1:]), true
   298  	}
   299  	// The presence of a slash implies there's an import path.
   300  	slash := strings.LastIndex(opt, "/")
   301  	if slash >= 0 {
   302  		return GoImportPath(opt), cleanPackageName(opt[slash+1:]), true
   303  	}
   304  	return "", cleanPackageName(opt), true
   305  }
   306  
   307  // goFileName returns the output name for the generated Go file.
   308  func (d *FileDescriptor) goFileName(pathType pathType, moduleRoot string) string {
   309  	name := *d.Name
   310  	if ext := path.Ext(name); ext == ".proto" || ext == ".protodevel" {
   311  		name = name[:len(name)-len(ext)]
   312  	}
   313  	name += ".pb.micro.go"
   314  
   315  	if pathType == pathTypeSourceRelative {
   316  		return name
   317  	}
   318  
   319  	// Does the file have a "go_package" option?
   320  	// If it does, it may override the filename.
   321  	if impPath, _, ok := d.goPackageOption(); ok && impPath != "" {
   322  		if pathType == pathModuleRoot && moduleRoot != "" {
   323  			root := moduleRoot
   324  			if !strings.HasSuffix(root, "/") {
   325  				root = root + "/"
   326  			}
   327  			name = strings.TrimPrefix(name, root)
   328  		} else {
   329  			// Replace the existing dirname with the declared import path.
   330  			_, name = path.Split(name)
   331  			name = path.Join(string(impPath), name)
   332  		}
   333  
   334  		return name
   335  	}
   336  
   337  	return name
   338  }
   339  
   340  func (d *FileDescriptor) addExport(obj Object, sym symbol) {
   341  	d.exported[obj] = append(d.exported[obj], sym)
   342  }
   343  
   344  // symbol is an interface representing an exported Go symbol.
   345  type symbol interface {
   346  	// GenerateAlias should generate an appropriate alias
   347  	// for the symbol from the named package.
   348  	GenerateAlias(g *Generator, filename string, pkg GoPackageName)
   349  }
   350  
   351  type messageSymbol struct {
   352  	sym                         string
   353  	hasExtensions, isMessageSet bool
   354  	oneofTypes                  []string
   355  }
   356  
   357  type getterSymbol struct {
   358  	name     string
   359  	typ      string
   360  	typeName string // canonical name in proto world; empty for proto.Message and similar
   361  	genType  bool   // whether typ contains a generated type (message/group/enum)
   362  }
   363  
   364  func (ms *messageSymbol) GenerateAlias(g *Generator, filename string, pkg GoPackageName) {
   365  	g.P("// ", ms.sym, " from public import ", filename)
   366  	g.P("type ", ms.sym, " = ", pkg, ".", ms.sym)
   367  	for _, name := range ms.oneofTypes {
   368  		g.P("type ", name, " = ", pkg, ".", name)
   369  	}
   370  }
   371  
   372  type enumSymbol struct {
   373  	name   string
   374  	proto3 bool // Whether this came from a proto3 file.
   375  }
   376  
   377  func (es enumSymbol) GenerateAlias(g *Generator, filename string, pkg GoPackageName) {
   378  	s := es.name
   379  	g.P("// ", s, " from public import ", filename)
   380  	g.P("type ", s, " = ", pkg, ".", s)
   381  	g.P("var ", s, "_name = ", pkg, ".", s, "_name")
   382  	g.P("var ", s, "_value = ", pkg, ".", s, "_value")
   383  }
   384  
   385  type constOrVarSymbol struct {
   386  	sym  string
   387  	typ  string // either "const" or "var"
   388  	cast string // if non-empty, a type cast is required (used for enums)
   389  }
   390  
   391  func (cs constOrVarSymbol) GenerateAlias(g *Generator, filename string, pkg GoPackageName) {
   392  	v := string(pkg) + "." + cs.sym
   393  	if cs.cast != "" {
   394  		v = cs.cast + "(" + v + ")"
   395  	}
   396  	g.P(cs.typ, " ", cs.sym, " = ", v)
   397  }
   398  
   399  // Object is an interface abstracting the abilities shared by enums, messages, extensions and imported objects.
   400  type Object interface {
   401  	GoImportPath() GoImportPath
   402  	TypeName() []string
   403  	File() *FileDescriptor
   404  }
   405  
   406  // Generator is the type whose methods generate the output, stored in the associated response structure.
   407  type Generator struct {
   408  	*bytes.Buffer
   409  
   410  	Request  *plugin.CodeGeneratorRequest  // The input.
   411  	Response *plugin.CodeGeneratorResponse // The output.
   412  
   413  	Param             map[string]string // Command-line parameters.
   414  	PackageImportPath string            // Go import path of the package we're generating code for
   415  	ImportPrefix      string            // String to prefix to imported package file names.
   416  	ImportMap         map[string]string // Mapping from .proto file name to import path
   417  	ModuleRoot        string            // Mapping from the module prefix
   418  
   419  	Pkg map[string]string // The names under which we import support packages
   420  
   421  	outputImportPath GoImportPath                   // Package we're generating code for.
   422  	allFiles         []*FileDescriptor              // All files in the tree
   423  	allFilesByName   map[string]*FileDescriptor     // All files by filename.
   424  	genFiles         []*FileDescriptor              // Those files we will generate output for.
   425  	file             *FileDescriptor                // The file we are compiling now.
   426  	packageNames     map[GoImportPath]GoPackageName // Imported package names in the current file.
   427  	usedPackages     map[GoImportPath]bool          // Packages used in current file.
   428  	usedPackageNames map[GoPackageName]bool         // Package names used in the current file.
   429  	addedImports     map[GoImportPath]bool          // Additional imports to emit.
   430  	typeNameToObject map[string]Object              // Key is a fully-qualified name in input syntax.
   431  	init             []string                       // Lines to emit in the init function.
   432  	indent           string
   433  	pathType         pathType // How to generate output filenames.
   434  	writeOutput      bool
   435  }
   436  
   437  type pathType int
   438  
   439  const (
   440  	pathTypeImport pathType = iota
   441  	pathTypeSourceRelative
   442  	pathModuleRoot
   443  )
   444  
   445  // New creates a new generator and allocates the request and response protobufs.
   446  func New() *Generator {
   447  	g := new(Generator)
   448  	g.Buffer = new(bytes.Buffer)
   449  	g.Request = new(plugin.CodeGeneratorRequest)
   450  	g.Response = new(plugin.CodeGeneratorResponse)
   451  	return g
   452  }
   453  
   454  // Error reports a problem, including an error, and exits the program.
   455  func (g *Generator) Error(err error, msgs ...string) {
   456  	s := strings.Join(msgs, " ") + ":" + err.Error()
   457  	log.Print("protoc-gen-micro: error:", s)
   458  	os.Exit(1)
   459  }
   460  
   461  // Fail reports a problem and exits the program.
   462  func (g *Generator) Fail(msgs ...string) {
   463  	s := strings.Join(msgs, " ")
   464  	log.Print("protoc-gen-micro: error:", s)
   465  	os.Exit(1)
   466  }
   467  
   468  // CommandLineParameters breaks the comma-separated list of key=value pairs
   469  // in the parameter (a member of the request protobuf) into a key/value map.
   470  // It then sets file name mappings defined by those entries.
   471  func (g *Generator) CommandLineParameters(parameter string) {
   472  	g.Param = make(map[string]string)
   473  	for _, p := range strings.Split(parameter, ",") {
   474  		if i := strings.Index(p, "="); i < 0 {
   475  			g.Param[p] = ""
   476  		} else {
   477  			g.Param[p[0:i]] = p[i+1:]
   478  		}
   479  	}
   480  
   481  	g.ImportMap = make(map[string]string)
   482  	pluginList := "none" // Default list of plugin names to enable (empty means all).
   483  	for k, v := range g.Param {
   484  		switch k {
   485  		case "import_prefix":
   486  			g.ImportPrefix = v
   487  		case "import_path":
   488  			g.PackageImportPath = v
   489  		case "module":
   490  			if g.pathType == pathTypeSourceRelative {
   491  				g.Fail(fmt.Sprintf(`Cannot set  module=%q after paths=source_relative`, v))
   492  			}
   493  			g.pathType = pathModuleRoot
   494  			g.ModuleRoot = v
   495  		case "paths":
   496  			switch v {
   497  			case "import":
   498  				g.pathType = pathTypeImport
   499  			case "source_relative":
   500  				if g.pathType == pathModuleRoot {
   501  					g.Fail("Cannot set paths=source_relative after setting module=<module_root>")
   502  				}
   503  				g.pathType = pathTypeSourceRelative
   504  			default:
   505  				g.Fail(fmt.Sprintf(`Unknown path type %q: want "import" or "source_relative".`, v))
   506  			}
   507  		case "plugins":
   508  			pluginList = v
   509  		default:
   510  			if len(k) > 0 && k[0] == 'M' {
   511  				g.ImportMap[k[1:]] = v
   512  			}
   513  		}
   514  	}
   515  	if pluginList != "" {
   516  		// Amend the set of plugins.
   517  		enabled := map[string]bool{
   518  			"micro": true,
   519  		}
   520  		for _, name := range strings.Split(pluginList, "+") {
   521  			enabled[name] = true
   522  		}
   523  		var nplugins []Plugin
   524  		for _, p := range plugins {
   525  			if enabled[p.Name()] {
   526  				nplugins = append(nplugins, p)
   527  			}
   528  		}
   529  		plugins = nplugins
   530  	}
   531  }
   532  
   533  // DefaultPackageName returns the package name printed for the object.
   534  // If its file is in a different package, it returns the package name we're using for this file, plus ".".
   535  // Otherwise it returns the empty string.
   536  func (g *Generator) DefaultPackageName(obj Object) string {
   537  	importPath := obj.GoImportPath()
   538  	if importPath == g.outputImportPath {
   539  		return ""
   540  	}
   541  	return string(g.GoPackageName(importPath)) + "."
   542  }
   543  
   544  // GoPackageName returns the name used for a package.
   545  func (g *Generator) GoPackageName(importPath GoImportPath) GoPackageName {
   546  	if name, ok := g.packageNames[importPath]; ok {
   547  		return name
   548  	}
   549  	name := cleanPackageName(baseName(string(importPath)))
   550  	for i, orig := 1, name; g.usedPackageNames[name] || isGoPredeclaredIdentifier[string(name)]; i++ {
   551  		name = orig + GoPackageName(strconv.Itoa(i))
   552  	}
   553  	g.packageNames[importPath] = name
   554  	g.usedPackageNames[name] = true
   555  	return name
   556  }
   557  
   558  // AddImport adds a package to the generated file's import section.
   559  // It returns the name used for the package.
   560  func (g *Generator) AddImport(importPath GoImportPath) GoPackageName {
   561  	g.addedImports[importPath] = true
   562  	return g.GoPackageName(importPath)
   563  }
   564  
   565  var globalPackageNames = map[GoPackageName]bool{
   566  	"fmt":   true,
   567  	"math":  true,
   568  	"proto": true,
   569  }
   570  
   571  // Create and remember a guaranteed unique package name. Pkg is the candidate name.
   572  // The FileDescriptor parameter is unused.
   573  func RegisterUniquePackageName(pkg string, f *FileDescriptor) string {
   574  	name := cleanPackageName(pkg)
   575  	for i, orig := 1, name; globalPackageNames[name]; i++ {
   576  		name = orig + GoPackageName(strconv.Itoa(i))
   577  	}
   578  	globalPackageNames[name] = true
   579  	return string(name)
   580  }
   581  
   582  var isGoKeyword = map[string]bool{
   583  	"break":       true,
   584  	"case":        true,
   585  	"chan":        true,
   586  	"const":       true,
   587  	"continue":    true,
   588  	"default":     true,
   589  	"else":        true,
   590  	"defer":       true,
   591  	"fallthrough": true,
   592  	"for":         true,
   593  	"func":        true,
   594  	"go":          true,
   595  	"goto":        true,
   596  	"if":          true,
   597  	"import":      true,
   598  	"interface":   true,
   599  	"map":         true,
   600  	"package":     true,
   601  	"range":       true,
   602  	"return":      true,
   603  	"select":      true,
   604  	"struct":      true,
   605  	"switch":      true,
   606  	"type":        true,
   607  	"var":         true,
   608  }
   609  
   610  var isGoPredeclaredIdentifier = map[string]bool{
   611  	"append":     true,
   612  	"bool":       true,
   613  	"byte":       true,
   614  	"cap":        true,
   615  	"close":      true,
   616  	"complex":    true,
   617  	"complex128": true,
   618  	"complex64":  true,
   619  	"copy":       true,
   620  	"delete":     true,
   621  	"error":      true,
   622  	"false":      true,
   623  	"float32":    true,
   624  	"float64":    true,
   625  	"imag":       true,
   626  	"int":        true,
   627  	"int16":      true,
   628  	"int32":      true,
   629  	"int64":      true,
   630  	"int8":       true,
   631  	"iota":       true,
   632  	"len":        true,
   633  	"make":       true,
   634  	"new":        true,
   635  	"nil":        true,
   636  	"panic":      true,
   637  	"print":      true,
   638  	"println":    true,
   639  	"real":       true,
   640  	"recover":    true,
   641  	"rune":       true,
   642  	"string":     true,
   643  	"true":       true,
   644  	"uint":       true,
   645  	"uint16":     true,
   646  	"uint32":     true,
   647  	"uint64":     true,
   648  	"uint8":      true,
   649  	"uintptr":    true,
   650  }
   651  
   652  func cleanPackageName(name string) GoPackageName {
   653  	name = strings.Map(badToUnderscore, name)
   654  	// Identifier must not be keyword or predeclared identifier: insert _.
   655  	if isGoKeyword[name] {
   656  		name = "_" + name
   657  	}
   658  	// Identifier must not begin with digit: insert _.
   659  	if r, _ := utf8.DecodeRuneInString(name); unicode.IsDigit(r) {
   660  		name = "_" + name
   661  	}
   662  	return GoPackageName(name)
   663  }
   664  
   665  // defaultGoPackage returns the package name to use,
   666  // derived from the import path of the package we're building code for.
   667  func (g *Generator) defaultGoPackage() GoPackageName {
   668  	p := g.PackageImportPath
   669  	if i := strings.LastIndex(p, "/"); i >= 0 {
   670  		p = p[i+1:]
   671  	}
   672  	return cleanPackageName(p)
   673  }
   674  
   675  // SetPackageNames sets the package name for this run.
   676  // The package name must agree across all files being generated.
   677  // It also defines unique package names for all imported files.
   678  func (g *Generator) SetPackageNames() {
   679  	g.outputImportPath = g.genFiles[0].importPath
   680  
   681  	defaultPackageNames := make(map[GoImportPath]GoPackageName)
   682  	for _, f := range g.genFiles {
   683  		if _, p, ok := f.goPackageOption(); ok {
   684  			defaultPackageNames[f.importPath] = p
   685  		}
   686  	}
   687  	for _, f := range g.genFiles {
   688  		if _, p, ok := f.goPackageOption(); ok {
   689  			// Source file: option go_package = "quux/bar";
   690  			f.packageName = p
   691  		} else if p, ok := defaultPackageNames[f.importPath]; ok {
   692  			// A go_package option in another file in the same package.
   693  			//
   694  			// This is a poor choice in general, since every source file should
   695  			// contain a go_package option. Supported mainly for historical
   696  			// compatibility.
   697  			f.packageName = p
   698  		} else if p := g.defaultGoPackage(); p != "" {
   699  			// Command-line: import_path=quux/bar.
   700  			//
   701  			// The import_path flag sets a package name for files which don't
   702  			// contain a go_package option.
   703  			f.packageName = p
   704  		} else if p := f.GetPackage(); p != "" {
   705  			// Source file: package quux.bar;
   706  			f.packageName = cleanPackageName(p)
   707  		} else {
   708  			// Source filename.
   709  			f.packageName = cleanPackageName(baseName(f.GetName()))
   710  		}
   711  	}
   712  
   713  	// Check that all files have a consistent package name and import path.
   714  	for _, f := range g.genFiles[1:] {
   715  		if a, b := g.genFiles[0].importPath, f.importPath; a != b {
   716  			g.Fail(fmt.Sprintf("inconsistent package import paths: %v, %v", a, b))
   717  		}
   718  		if a, b := g.genFiles[0].packageName, f.packageName; a != b {
   719  			g.Fail(fmt.Sprintf("inconsistent package names: %v, %v", a, b))
   720  		}
   721  	}
   722  
   723  	// Names of support packages. These never vary (if there are conflicts,
   724  	// we rename the conflicting package), so this could be removed someday.
   725  	g.Pkg = map[string]string{
   726  		"fmt":   "fmt",
   727  		"math":  "math",
   728  		"proto": "proto",
   729  	}
   730  }
   731  
   732  // WrapTypes walks the incoming data, wrapping DescriptorProtos, EnumDescriptorProtos
   733  // and FileDescriptorProtos into file-referenced objects within the Generator.
   734  // It also creates the list of files to generate and so should be called before GenerateAllFiles.
   735  func (g *Generator) WrapTypes() {
   736  	g.allFiles = make([]*FileDescriptor, 0, len(g.Request.ProtoFile))
   737  	g.allFilesByName = make(map[string]*FileDescriptor, len(g.allFiles))
   738  	genFileNames := make(map[string]bool)
   739  	for _, n := range g.Request.FileToGenerate {
   740  		genFileNames[n] = true
   741  	}
   742  	for _, f := range g.Request.ProtoFile {
   743  		fd := &FileDescriptor{
   744  			FileDescriptorProto: f,
   745  			exported:            make(map[Object][]symbol),
   746  			proto3:              fileIsProto3(f),
   747  		}
   748  		// The import path may be set in a number of ways.
   749  		if substitution, ok := g.ImportMap[f.GetName()]; ok {
   750  			// Command-line: M=foo.proto=quux/bar.
   751  			//
   752  			// Explicit mapping of source file to import path.
   753  			fd.importPath = GoImportPath(substitution)
   754  		} else if genFileNames[f.GetName()] && g.PackageImportPath != "" {
   755  			// Command-line: import_path=quux/bar.
   756  			//
   757  			// The import_path flag sets the import path for every file that
   758  			// we generate code for.
   759  			fd.importPath = GoImportPath(g.PackageImportPath)
   760  		} else if p, _, _ := fd.goPackageOption(); p != "" {
   761  			// Source file: option go_package = "quux/bar";
   762  			//
   763  			// The go_package option sets the import path. Most users should use this.
   764  			fd.importPath = p
   765  		} else {
   766  			// Source filename.
   767  			//
   768  			// Last resort when nothing else is available.
   769  			fd.importPath = GoImportPath(path.Dir(f.GetName()))
   770  		}
   771  		// We must wrap the descriptors before we wrap the enums
   772  		fd.desc = wrapDescriptors(fd)
   773  		g.buildNestedDescriptors(fd.desc)
   774  		fd.enum = wrapEnumDescriptors(fd, fd.desc)
   775  		g.buildNestedEnums(fd.desc, fd.enum)
   776  		fd.ext = wrapExtensions(fd)
   777  		extractComments(fd)
   778  		g.allFiles = append(g.allFiles, fd)
   779  		g.allFilesByName[f.GetName()] = fd
   780  	}
   781  	for _, fd := range g.allFiles {
   782  		fd.imp = wrapImported(fd, g)
   783  	}
   784  
   785  	g.genFiles = make([]*FileDescriptor, 0, len(g.Request.FileToGenerate))
   786  	for _, fileName := range g.Request.FileToGenerate {
   787  		fd := g.allFilesByName[fileName]
   788  		if fd == nil {
   789  			g.Fail("could not find file named", fileName)
   790  		}
   791  		g.genFiles = append(g.genFiles, fd)
   792  	}
   793  }
   794  
   795  // Scan the descriptors in this file.  For each one, build the slice of nested descriptors
   796  func (g *Generator) buildNestedDescriptors(descs []*Descriptor) {
   797  	for _, desc := range descs {
   798  		if len(desc.NestedType) != 0 {
   799  			for _, nest := range descs {
   800  				if nest.parent == desc {
   801  					desc.nested = append(desc.nested, nest)
   802  				}
   803  			}
   804  			if len(desc.nested) != len(desc.NestedType) {
   805  				g.Fail("internal error: nesting failure for", desc.GetName())
   806  			}
   807  		}
   808  	}
   809  }
   810  
   811  func (g *Generator) buildNestedEnums(descs []*Descriptor, enums []*EnumDescriptor) {
   812  	for _, desc := range descs {
   813  		if len(desc.EnumType) != 0 {
   814  			for _, enum := range enums {
   815  				if enum.parent == desc {
   816  					desc.enums = append(desc.enums, enum)
   817  				}
   818  			}
   819  			if len(desc.enums) != len(desc.EnumType) {
   820  				g.Fail("internal error: enum nesting failure for", desc.GetName())
   821  			}
   822  		}
   823  	}
   824  }
   825  
   826  // Construct the Descriptor
   827  func newDescriptor(desc *descriptor.DescriptorProto, parent *Descriptor, file *FileDescriptor, index int) *Descriptor {
   828  	d := &Descriptor{
   829  		common:          common{file},
   830  		DescriptorProto: desc,
   831  		parent:          parent,
   832  		index:           index,
   833  	}
   834  	if parent == nil {
   835  		d.path = fmt.Sprintf("%d,%d", messagePath, index)
   836  	} else {
   837  		d.path = fmt.Sprintf("%s,%d,%d", parent.path, messageMessagePath, index)
   838  	}
   839  
   840  	// The only way to distinguish a group from a message is whether
   841  	// the containing message has a TYPE_GROUP field that matches.
   842  	if parent != nil {
   843  		parts := d.TypeName()
   844  		if file.Package != nil {
   845  			parts = append([]string{*file.Package}, parts...)
   846  		}
   847  		exp := "." + strings.Join(parts, ".")
   848  		for _, field := range parent.Field {
   849  			if field.GetType() == descriptor.FieldDescriptorProto_TYPE_GROUP && field.GetTypeName() == exp {
   850  				d.group = true
   851  				break
   852  			}
   853  		}
   854  	}
   855  
   856  	for _, field := range desc.Extension {
   857  		d.ext = append(d.ext, &ExtensionDescriptor{common{file}, field, d})
   858  	}
   859  
   860  	return d
   861  }
   862  
   863  // Return a slice of all the Descriptors defined within this file
   864  func wrapDescriptors(file *FileDescriptor) []*Descriptor {
   865  	sl := make([]*Descriptor, 0, len(file.MessageType)+10)
   866  	for i, desc := range file.MessageType {
   867  		sl = wrapThisDescriptor(sl, desc, nil, file, i)
   868  	}
   869  	return sl
   870  }
   871  
   872  // Wrap this Descriptor, recursively
   873  func wrapThisDescriptor(sl []*Descriptor, desc *descriptor.DescriptorProto, parent *Descriptor, file *FileDescriptor, index int) []*Descriptor {
   874  	sl = append(sl, newDescriptor(desc, parent, file, index))
   875  	me := sl[len(sl)-1]
   876  	for i, nested := range desc.NestedType {
   877  		sl = wrapThisDescriptor(sl, nested, me, file, i)
   878  	}
   879  	return sl
   880  }
   881  
   882  // Construct the EnumDescriptor
   883  func newEnumDescriptor(desc *descriptor.EnumDescriptorProto, parent *Descriptor, file *FileDescriptor, index int) *EnumDescriptor {
   884  	ed := &EnumDescriptor{
   885  		common:              common{file},
   886  		EnumDescriptorProto: desc,
   887  		parent:              parent,
   888  		index:               index,
   889  	}
   890  	if parent == nil {
   891  		ed.path = fmt.Sprintf("%d,%d", enumPath, index)
   892  	} else {
   893  		ed.path = fmt.Sprintf("%s,%d,%d", parent.path, messageEnumPath, index)
   894  	}
   895  	return ed
   896  }
   897  
   898  // Return a slice of all the EnumDescriptors defined within this file
   899  func wrapEnumDescriptors(file *FileDescriptor, descs []*Descriptor) []*EnumDescriptor {
   900  	sl := make([]*EnumDescriptor, 0, len(file.EnumType)+10)
   901  	// Top-level enums.
   902  	for i, enum := range file.EnumType {
   903  		sl = append(sl, newEnumDescriptor(enum, nil, file, i))
   904  	}
   905  	// Enums within messages. Enums within embedded messages appear in the outer-most message.
   906  	for _, nested := range descs {
   907  		for i, enum := range nested.EnumType {
   908  			sl = append(sl, newEnumDescriptor(enum, nested, file, i))
   909  		}
   910  	}
   911  	return sl
   912  }
   913  
   914  // Return a slice of all the top-level ExtensionDescriptors defined within this file.
   915  func wrapExtensions(file *FileDescriptor) []*ExtensionDescriptor {
   916  	var sl []*ExtensionDescriptor
   917  	for _, field := range file.Extension {
   918  		sl = append(sl, &ExtensionDescriptor{common{file}, field, nil})
   919  	}
   920  	return sl
   921  }
   922  
   923  // Return a slice of all the types that are publicly imported into this file.
   924  func wrapImported(file *FileDescriptor, g *Generator) (sl []*ImportedDescriptor) {
   925  	for _, index := range file.PublicDependency {
   926  		df := g.fileByName(file.Dependency[index])
   927  		for _, d := range df.desc {
   928  			if d.GetOptions().GetMapEntry() {
   929  				continue
   930  			}
   931  			sl = append(sl, &ImportedDescriptor{common{file}, d})
   932  		}
   933  		for _, e := range df.enum {
   934  			sl = append(sl, &ImportedDescriptor{common{file}, e})
   935  		}
   936  		for _, ext := range df.ext {
   937  			sl = append(sl, &ImportedDescriptor{common{file}, ext})
   938  		}
   939  	}
   940  	return
   941  }
   942  
   943  func extractComments(file *FileDescriptor) {
   944  	file.comments = make(map[string]*descriptor.SourceCodeInfo_Location)
   945  	for _, loc := range file.GetSourceCodeInfo().GetLocation() {
   946  		if loc.LeadingComments == nil {
   947  			continue
   948  		}
   949  		var p []string
   950  		for _, n := range loc.Path {
   951  			p = append(p, strconv.Itoa(int(n)))
   952  		}
   953  		file.comments[strings.Join(p, ",")] = loc
   954  	}
   955  }
   956  
   957  // BuildTypeNameMap builds the map from fully qualified type names to objects.
   958  // The key names for the map come from the input data, which puts a period at the beginning.
   959  // It should be called after SetPackageNames and before GenerateAllFiles.
   960  func (g *Generator) BuildTypeNameMap() {
   961  	g.typeNameToObject = make(map[string]Object)
   962  	for _, f := range g.allFiles {
   963  		// The names in this loop are defined by the proto world, not us, so the
   964  		// package name may be empty.  If so, the dotted package name of X will
   965  		// be ".X"; otherwise it will be ".pkg.X".
   966  		dottedPkg := "." + f.GetPackage()
   967  		if dottedPkg != "." {
   968  			dottedPkg += "."
   969  		}
   970  		for _, enum := range f.enum {
   971  			name := dottedPkg + dottedSlice(enum.TypeName())
   972  			g.typeNameToObject[name] = enum
   973  		}
   974  		for _, desc := range f.desc {
   975  			name := dottedPkg + dottedSlice(desc.TypeName())
   976  			g.typeNameToObject[name] = desc
   977  		}
   978  	}
   979  }
   980  
   981  // ObjectNamed, given a fully-qualified input type name as it appears in the input data,
   982  // returns the descriptor for the message or enum with that name.
   983  func (g *Generator) ObjectNamed(typeName string) Object {
   984  	o, ok := g.typeNameToObject[typeName]
   985  	if !ok {
   986  		g.Fail("can't find object with type", typeName)
   987  	}
   988  	return o
   989  }
   990  
   991  // AnnotatedAtoms is a list of atoms (as consumed by P) that records the file name and proto AST path from which they originated.
   992  type AnnotatedAtoms struct {
   993  	source string
   994  	path   string
   995  	atoms  []interface{}
   996  }
   997  
   998  // Annotate records the file name and proto AST path of a list of atoms
   999  // so that a later call to P can emit a link from each atom to its origin.
  1000  func Annotate(file *FileDescriptor, path string, atoms ...interface{}) *AnnotatedAtoms {
  1001  	return &AnnotatedAtoms{source: *file.Name, path: path, atoms: atoms}
  1002  }
  1003  
  1004  // printAtom prints the (atomic, non-annotation) argument to the generated output.
  1005  func (g *Generator) printAtom(v interface{}) {
  1006  	switch v := v.(type) {
  1007  	case string:
  1008  		g.WriteString(v)
  1009  	case *string:
  1010  		g.WriteString(*v)
  1011  	case bool:
  1012  		fmt.Fprint(g, v)
  1013  	case *bool:
  1014  		fmt.Fprint(g, *v)
  1015  	case int:
  1016  		fmt.Fprint(g, v)
  1017  	case *int32:
  1018  		fmt.Fprint(g, *v)
  1019  	case *int64:
  1020  		fmt.Fprint(g, *v)
  1021  	case float64:
  1022  		fmt.Fprint(g, v)
  1023  	case *float64:
  1024  		fmt.Fprint(g, *v)
  1025  	case GoPackageName:
  1026  		g.WriteString(string(v))
  1027  	case GoImportPath:
  1028  		g.WriteString(strconv.Quote(string(v)))
  1029  	default:
  1030  		g.Fail(fmt.Sprintf("unknown type in printer: %T", v))
  1031  	}
  1032  }
  1033  
  1034  // P prints the arguments to the generated output.  It handles strings and int32s, plus
  1035  // handling indirections because they may be *string, etc.  Any inputs of type AnnotatedAtoms may emit
  1036  // annotations in a .meta file in addition to outputting the atoms themselves (if g.annotateCode
  1037  // is true).
  1038  func (g *Generator) P(str ...interface{}) {
  1039  	if !g.writeOutput {
  1040  		return
  1041  	}
  1042  	g.WriteString(g.indent)
  1043  	for _, v := range str {
  1044  		switch v := v.(type) {
  1045  		case *AnnotatedAtoms:
  1046  			for _, v := range v.atoms {
  1047  				g.printAtom(v)
  1048  			}
  1049  		default:
  1050  			g.printAtom(v)
  1051  		}
  1052  	}
  1053  	g.WriteByte('\n')
  1054  }
  1055  
  1056  // addInitf stores the given statement to be printed inside the file's init function.
  1057  // The statement is given as a format specifier and arguments.
  1058  func (g *Generator) addInitf(stmt string, a ...interface{}) {
  1059  	g.init = append(g.init, fmt.Sprintf(stmt, a...))
  1060  }
  1061  
  1062  // In Indents the output one tab stop.
  1063  func (g *Generator) In() { g.indent += "\t" }
  1064  
  1065  // Out unindents the output one tab stop.
  1066  func (g *Generator) Out() {
  1067  	if len(g.indent) > 0 {
  1068  		g.indent = g.indent[1:]
  1069  	}
  1070  }
  1071  
  1072  // GenerateAllFiles generates the output for all the files we're outputting.
  1073  func (g *Generator) GenerateAllFiles() {
  1074  	// Initialize the plugins
  1075  	for _, p := range plugins {
  1076  		p.Init(g)
  1077  	}
  1078  	// Generate the output. The generator runs for every file, even the files
  1079  	// that we don't generate output for, so that we can collate the full list
  1080  	// of exported symbols to support public imports.
  1081  	genFileMap := make(map[*FileDescriptor]bool, len(g.genFiles))
  1082  	for _, file := range g.genFiles {
  1083  		genFileMap[file] = true
  1084  	}
  1085  	for _, file := range g.allFiles {
  1086  		g.Reset()
  1087  		g.writeOutput = genFileMap[file]
  1088  		g.generate(file)
  1089  		if !g.writeOutput {
  1090  			continue
  1091  		}
  1092  		fname := file.goFileName(g.pathType, g.ModuleRoot)
  1093  		g.Response.File = append(g.Response.File, &plugin.CodeGeneratorResponse_File{
  1094  			Name:    proto.String(fname),
  1095  			Content: proto.String(g.String()),
  1096  		})
  1097  	}
  1098  	g.Response.SupportedFeatures = proto.Uint64(SupportedFeatures)
  1099  }
  1100  
  1101  // Run all the plugins associated with the file.
  1102  func (g *Generator) runPlugins(file *FileDescriptor) {
  1103  	for _, p := range plugins {
  1104  		p.Generate(file)
  1105  	}
  1106  }
  1107  
  1108  // Fill the response protocol buffer with the generated output for all the files we're
  1109  // supposed to generate.
  1110  func (g *Generator) generate(file *FileDescriptor) {
  1111  	g.file = file
  1112  	g.usedPackages = make(map[GoImportPath]bool)
  1113  	g.packageNames = make(map[GoImportPath]GoPackageName)
  1114  	g.usedPackageNames = make(map[GoPackageName]bool)
  1115  	g.addedImports = make(map[GoImportPath]bool)
  1116  	for name := range globalPackageNames {
  1117  		g.usedPackageNames[name] = true
  1118  	}
  1119  
  1120  	for _, td := range g.file.imp {
  1121  		g.generateImported(td)
  1122  	}
  1123  
  1124  	g.generateInitFunction()
  1125  
  1126  	// Run the plugins before the imports so we know which imports are necessary.
  1127  	g.runPlugins(file)
  1128  
  1129  	// Generate header and imports last, though they appear first in the output.
  1130  	rem := g.Buffer
  1131  	g.Buffer = new(bytes.Buffer)
  1132  	g.generateHeader()
  1133  	g.generateImports()
  1134  	if !g.writeOutput {
  1135  		return
  1136  	}
  1137  	g.Write(rem.Bytes())
  1138  
  1139  	// Reformat generated code and patch annotation locations.
  1140  	fset := token.NewFileSet()
  1141  	original := g.Bytes()
  1142  	fileAST, err := parser.ParseFile(fset, "", original, parser.ParseComments)
  1143  	if err != nil {
  1144  		// Print out the bad code with line numbers.
  1145  		// This should never happen in practice, but it can while changing generated code,
  1146  		// so consider this a debugging aid.
  1147  		var src bytes.Buffer
  1148  		s := bufio.NewScanner(bytes.NewReader(original))
  1149  		for line := 1; s.Scan(); line++ {
  1150  			fmt.Fprintf(&src, "%5d\t%s\n", line, s.Bytes())
  1151  		}
  1152  		g.Fail("bad Go source code was generated:", err.Error(), "\n"+src.String())
  1153  	}
  1154  	ast.SortImports(fset, fileAST)
  1155  	g.Reset()
  1156  	err = (&printer.Config{Mode: printer.TabIndent | printer.UseSpaces, Tabwidth: 8}).Fprint(g, fset, fileAST)
  1157  	if err != nil {
  1158  		g.Fail("generated Go source code could not be reformatted:", err.Error())
  1159  	}
  1160  }
  1161  
  1162  // Generate the header, including package definition
  1163  func (g *Generator) generateHeader() {
  1164  	g.P("// Code generated by protoc-gen-micro. DO NOT EDIT.")
  1165  	if g.file.GetOptions().GetDeprecated() {
  1166  		g.P("// ", g.file.Name, " is a deprecated file.")
  1167  	} else {
  1168  		g.P("// source: ", g.file.Name)
  1169  	}
  1170  	g.P()
  1171  	g.PrintComments(strconv.Itoa(packagePath))
  1172  	g.P()
  1173  	g.P("package ", g.file.packageName)
  1174  	g.P()
  1175  }
  1176  
  1177  // deprecationComment is the standard comment added to deprecated
  1178  // messages, fields, enums, and enum values.
  1179  var deprecationComment = "// Deprecated: Do not use."
  1180  
  1181  // PrintComments prints any comments from the source .proto file.
  1182  // The path is a comma-separated list of integers.
  1183  // It returns an indication of whether any comments were printed.
  1184  // See descriptor.proto for its format.
  1185  func (g *Generator) PrintComments(path string) bool {
  1186  	if !g.writeOutput {
  1187  		return false
  1188  	}
  1189  	if c, ok := g.makeComments(path); ok {
  1190  		g.P(c)
  1191  		return true
  1192  	}
  1193  	return false
  1194  }
  1195  
  1196  // makeComments generates the comment string for the field, no "\n" at the end
  1197  func (g *Generator) makeComments(path string) (string, bool) {
  1198  	loc, ok := g.file.comments[path]
  1199  	if !ok {
  1200  		return "", false
  1201  	}
  1202  	w := new(bytes.Buffer)
  1203  	nl := ""
  1204  	for _, line := range strings.Split(strings.TrimSuffix(loc.GetLeadingComments(), "\n"), "\n") {
  1205  		fmt.Fprintf(w, "%s//%s", nl, line)
  1206  		nl = "\n"
  1207  	}
  1208  	return w.String(), true
  1209  }
  1210  
  1211  func (g *Generator) fileByName(filename string) *FileDescriptor {
  1212  	return g.allFilesByName[filename]
  1213  }
  1214  
  1215  // weak returns whether the ith import of the current file is a weak import.
  1216  func (g *Generator) weak(i int32) bool {
  1217  	for _, j := range g.file.WeakDependency {
  1218  		if j == i {
  1219  			return true
  1220  		}
  1221  	}
  1222  	return false
  1223  }
  1224  
  1225  // Generate the imports
  1226  func (g *Generator) generateImports() {
  1227  	imports := make(map[GoImportPath]GoPackageName)
  1228  	for i, s := range g.file.Dependency {
  1229  		fd := g.fileByName(s)
  1230  		importPath := fd.importPath
  1231  		// Do not import our own package.
  1232  		if importPath == g.file.importPath {
  1233  			continue
  1234  		}
  1235  		// Do not import weak imports.
  1236  		if g.weak(int32(i)) {
  1237  			continue
  1238  		}
  1239  		// Do not import a package twice.
  1240  		if _, ok := imports[importPath]; ok {
  1241  			continue
  1242  		}
  1243  		// We need to import all the dependencies, even if we don't reference them,
  1244  		// because other code and tools depend on having the full transitive closure
  1245  		// of protocol buffer types in the binary.
  1246  		packageName := g.GoPackageName(importPath)
  1247  		if _, ok := g.usedPackages[importPath]; !ok {
  1248  			packageName = "_"
  1249  		}
  1250  		imports[importPath] = packageName
  1251  	}
  1252  	for importPath := range g.addedImports {
  1253  		imports[importPath] = g.GoPackageName(importPath)
  1254  	}
  1255  	// We almost always need a proto import.  Rather than computing when we
  1256  	// do, which is tricky when there's a plugin, just import it and
  1257  	// reference it later. The same argument applies to the fmt and math packages.
  1258  	g.P("import (")
  1259  	g.P(g.Pkg["fmt"] + ` "fmt"`)
  1260  	g.P(g.Pkg["math"] + ` "math"`)
  1261  	g.P(g.Pkg["proto"]+" ", GoImportPath(g.ImportPrefix)+"google.golang.org/protobuf/proto")
  1262  	for importPath, packageName := range imports {
  1263  		g.P(packageName, " ", GoImportPath(g.ImportPrefix)+importPath)
  1264  	}
  1265  	g.P(")")
  1266  	g.P()
  1267  	// TODO: may need to worry about uniqueness across plugins
  1268  	for _, p := range plugins {
  1269  		p.GenerateImports(g.file, imports)
  1270  		g.P()
  1271  	}
  1272  	g.P("// Reference imports to suppress errors if they are not otherwise used.")
  1273  	g.P("var _ = ", g.Pkg["proto"], ".Marshal")
  1274  	g.P("var _ = ", g.Pkg["fmt"], ".Errorf")
  1275  	g.P("var _ = ", g.Pkg["math"], ".Inf")
  1276  	g.P()
  1277  }
  1278  
  1279  func (g *Generator) generateImported(id *ImportedDescriptor) {
  1280  	df := id.o.File()
  1281  	filename := *df.Name
  1282  	if df.importPath == g.file.importPath {
  1283  		// Don't generate type aliases for files in the same Go package as this one.
  1284  		return
  1285  	}
  1286  	if !supportTypeAliases {
  1287  		g.Fail(fmt.Sprintf("%s: public imports require at least go1.9", filename))
  1288  	}
  1289  	g.usedPackages[df.importPath] = true
  1290  
  1291  	for _, sym := range df.exported[id.o] {
  1292  		sym.GenerateAlias(g, filename, g.GoPackageName(df.importPath))
  1293  	}
  1294  
  1295  	g.P()
  1296  }
  1297  
  1298  // Generate the enum definitions for this EnumDescriptor.
  1299  func (g *Generator) generateEnum(enum *EnumDescriptor) {
  1300  	// The full type name
  1301  	typeName := enum.TypeName()
  1302  	// The full type name, CamelCased.
  1303  	ccTypeName := CamelCaseSlice(typeName)
  1304  	ccPrefix := enum.prefix()
  1305  
  1306  	deprecatedEnum := ""
  1307  	if enum.GetOptions().GetDeprecated() {
  1308  		deprecatedEnum = deprecationComment
  1309  	}
  1310  	g.PrintComments(enum.path)
  1311  	g.P("type ", Annotate(enum.file, enum.path, ccTypeName), " int32", deprecatedEnum)
  1312  	g.file.addExport(enum, enumSymbol{ccTypeName, enum.proto3()})
  1313  	g.P("const (")
  1314  	for i, e := range enum.Value {
  1315  		etorPath := fmt.Sprintf("%s,%d,%d", enum.path, enumValuePath, i)
  1316  		g.PrintComments(etorPath)
  1317  
  1318  		deprecatedValue := ""
  1319  		if e.GetOptions().GetDeprecated() {
  1320  			deprecatedValue = deprecationComment
  1321  		}
  1322  
  1323  		name := ccPrefix + *e.Name
  1324  		g.P(Annotate(enum.file, etorPath, name), " ", ccTypeName, " = ", e.Number, " ", deprecatedValue)
  1325  		g.file.addExport(enum, constOrVarSymbol{name, "const", ccTypeName})
  1326  	}
  1327  	g.P(")")
  1328  	g.P()
  1329  	g.P("var ", ccTypeName, "_name = map[int32]string{")
  1330  	generated := make(map[int32]bool) // avoid duplicate values
  1331  	for _, e := range enum.Value {
  1332  		duplicate := ""
  1333  		if _, present := generated[*e.Number]; present {
  1334  			duplicate = "// Duplicate value: "
  1335  		}
  1336  		g.P(duplicate, e.Number, ": ", strconv.Quote(*e.Name), ",")
  1337  		generated[*e.Number] = true
  1338  	}
  1339  	g.P("}")
  1340  	g.P()
  1341  	g.P("var ", ccTypeName, "_value = map[string]int32{")
  1342  	for _, e := range enum.Value {
  1343  		g.P(strconv.Quote(*e.Name), ": ", e.Number, ",")
  1344  	}
  1345  	g.P("}")
  1346  	g.P()
  1347  
  1348  	if !enum.proto3() {
  1349  		g.P("func (x ", ccTypeName, ") Enum() *", ccTypeName, " {")
  1350  		g.P("p := new(", ccTypeName, ")")
  1351  		g.P("*p = x")
  1352  		g.P("return p")
  1353  		g.P("}")
  1354  		g.P()
  1355  	}
  1356  
  1357  	g.P("func (x ", ccTypeName, ") String() string {")
  1358  	g.P("return ", g.Pkg["proto"], ".EnumName(", ccTypeName, "_name, int32(x))")
  1359  	g.P("}")
  1360  	g.P()
  1361  
  1362  	if !enum.proto3() {
  1363  		g.P("func (x *", ccTypeName, ") UnmarshalJSON(data []byte) error {")
  1364  		g.P("value, err := ", g.Pkg["proto"], ".UnmarshalJSONEnum(", ccTypeName, `_value, data, "`, ccTypeName, `")`)
  1365  		g.P("if err != nil {")
  1366  		g.P("return err")
  1367  		g.P("}")
  1368  		g.P("*x = ", ccTypeName, "(value)")
  1369  		g.P("return nil")
  1370  		g.P("}")
  1371  		g.P()
  1372  	}
  1373  
  1374  	var indexes []string
  1375  	for m := enum.parent; m != nil; m = m.parent {
  1376  		// XXX: skip groups?
  1377  		indexes = append([]string{strconv.Itoa(m.index)}, indexes...)
  1378  	}
  1379  	indexes = append(indexes, strconv.Itoa(enum.index))
  1380  	g.P("func (", ccTypeName, ") EnumDescriptor() ([]byte, []int) {")
  1381  	g.P("return ", g.file.VarName(), ", []int{", strings.Join(indexes, ", "), "}")
  1382  	g.P("}")
  1383  	g.P()
  1384  	if enum.file.GetPackage() == "google.protobuf" && enum.GetName() == "NullValue" {
  1385  		g.P("func (", ccTypeName, `) XXX_WellKnownType() string { return "`, enum.GetName(), `" }`)
  1386  		g.P()
  1387  	}
  1388  
  1389  	g.generateEnumRegistration(enum)
  1390  }
  1391  
  1392  // The tag is a string like "varint,2,opt,name=fieldname,def=7" that
  1393  // identifies details of the field for the protocol buffer marshaling and unmarshaling
  1394  // code.  The fields are:
  1395  //
  1396  //	wire encoding
  1397  //	protocol tag number
  1398  //	opt,req,rep for optional, required, or repeated
  1399  //	packed whether the encoding is "packed" (optional; repeated primitives only)
  1400  //	name= the original declared name
  1401  //	enum= the name of the enum type if it is an enum-typed field.
  1402  //	proto3 if this field is in a proto3 message
  1403  //	def= string representation of the default value, if any.
  1404  //
  1405  // The default value must be in a representation that can be used at run-time
  1406  // to generate the default value. Thus bools become 0 and 1, for instance.
  1407  func (g *Generator) goTag(message *Descriptor, field *descriptor.FieldDescriptorProto, wiretype string) string {
  1408  	optrepreq := ""
  1409  	switch {
  1410  	case isOptional(field):
  1411  		optrepreq = "opt"
  1412  	case isRequired(field):
  1413  		optrepreq = "req"
  1414  	case isRepeated(field):
  1415  		optrepreq = "rep"
  1416  	}
  1417  	var defaultValue string
  1418  	if dv := field.DefaultValue; dv != nil { // set means an explicit default
  1419  		defaultValue = *dv
  1420  		// Some types need tweaking.
  1421  		switch *field.Type {
  1422  		case descriptor.FieldDescriptorProto_TYPE_BOOL:
  1423  			if defaultValue == "true" {
  1424  				defaultValue = "1"
  1425  			} else {
  1426  				defaultValue = "0"
  1427  			}
  1428  		case descriptor.FieldDescriptorProto_TYPE_STRING,
  1429  			descriptor.FieldDescriptorProto_TYPE_BYTES:
  1430  			// Nothing to do. Quoting is done for the whole tag.
  1431  		case descriptor.FieldDescriptorProto_TYPE_ENUM:
  1432  			// For enums we need to provide the integer constant.
  1433  			obj := g.ObjectNamed(field.GetTypeName())
  1434  			if id, ok := obj.(*ImportedDescriptor); ok {
  1435  				// It is an enum that was publicly imported.
  1436  				// We need the underlying type.
  1437  				obj = id.o
  1438  			}
  1439  			enum, ok := obj.(*EnumDescriptor)
  1440  			if !ok {
  1441  				log.Printf("obj is a %T", obj)
  1442  				if id, ok := obj.(*ImportedDescriptor); ok {
  1443  					log.Printf("id.o is a %T", id.o)
  1444  				}
  1445  				g.Fail("unknown enum type", CamelCaseSlice(obj.TypeName()))
  1446  			}
  1447  			defaultValue = enum.integerValueAsString(defaultValue)
  1448  		case descriptor.FieldDescriptorProto_TYPE_FLOAT:
  1449  			if def := defaultValue; def != "inf" && def != "-inf" && def != "nan" {
  1450  				if f, err := strconv.ParseFloat(defaultValue, 32); err == nil {
  1451  					defaultValue = fmt.Sprint(float32(f))
  1452  				}
  1453  			}
  1454  		case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
  1455  			if def := defaultValue; def != "inf" && def != "-inf" && def != "nan" {
  1456  				if f, err := strconv.ParseFloat(defaultValue, 64); err == nil {
  1457  					defaultValue = fmt.Sprint(f)
  1458  				}
  1459  			}
  1460  		}
  1461  		defaultValue = ",def=" + defaultValue
  1462  	}
  1463  	enum := ""
  1464  	if *field.Type == descriptor.FieldDescriptorProto_TYPE_ENUM {
  1465  		// We avoid using obj.GoPackageName(), because we want to use the
  1466  		// original (proto-world) package name.
  1467  		obj := g.ObjectNamed(field.GetTypeName())
  1468  		if id, ok := obj.(*ImportedDescriptor); ok {
  1469  			obj = id.o
  1470  		}
  1471  		enum = ",enum="
  1472  		if pkg := obj.File().GetPackage(); pkg != "" {
  1473  			enum += pkg + "."
  1474  		}
  1475  		enum += CamelCaseSlice(obj.TypeName())
  1476  	}
  1477  	packed := ""
  1478  	if (field.Options != nil && field.Options.GetPacked()) ||
  1479  		// Per https://developers.google.com/protocol-buffers/docs/proto3#simple:
  1480  		// "In proto3, repeated fields of scalar numeric types use packed encoding by default."
  1481  		(message.proto3() && (field.Options == nil || field.Options.Packed == nil) &&
  1482  			isRepeated(field) && isScalar(field)) {
  1483  		packed = ",packed"
  1484  	}
  1485  	fieldName := field.GetName()
  1486  	name := fieldName
  1487  	if *field.Type == descriptor.FieldDescriptorProto_TYPE_GROUP {
  1488  		// We must use the type name for groups instead of
  1489  		// the field name to preserve capitalization.
  1490  		// type_name in FieldDescriptorProto is fully-qualified,
  1491  		// but we only want the local part.
  1492  		name = *field.TypeName
  1493  		if i := strings.LastIndex(name, "."); i >= 0 {
  1494  			name = name[i+1:]
  1495  		}
  1496  	}
  1497  	if json := field.GetJsonName(); field.Extendee == nil && json != "" && json != name {
  1498  		// TODO: escaping might be needed, in which case
  1499  		// perhaps this should be in its own "json" tag.
  1500  		name += ",json=" + json
  1501  	}
  1502  	name = ",name=" + name
  1503  	if message.proto3() {
  1504  		name += ",proto3"
  1505  	}
  1506  	oneof := ""
  1507  	if field.OneofIndex != nil {
  1508  		oneof = ",oneof"
  1509  	}
  1510  	return strconv.Quote(fmt.Sprintf("%s,%d,%s%s%s%s%s%s",
  1511  		wiretype,
  1512  		field.GetNumber(),
  1513  		optrepreq,
  1514  		packed,
  1515  		name,
  1516  		enum,
  1517  		oneof,
  1518  		defaultValue))
  1519  }
  1520  
  1521  func needsStar(typ descriptor.FieldDescriptorProto_Type) bool {
  1522  	switch typ {
  1523  	case descriptor.FieldDescriptorProto_TYPE_GROUP:
  1524  		return false
  1525  	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
  1526  		return false
  1527  	case descriptor.FieldDescriptorProto_TYPE_BYTES:
  1528  		return false
  1529  	}
  1530  	return true
  1531  }
  1532  
  1533  // TypeName is the printed name appropriate for an item. If the object is in the current file,
  1534  // TypeName drops the package name and underscores the rest.
  1535  // Otherwise the object is from another package; and the result is the underscored
  1536  // package name followed by the item name.
  1537  // The result always has an initial capital.
  1538  func (g *Generator) TypeName(obj Object) string {
  1539  	return g.DefaultPackageName(obj) + CamelCaseSlice(obj.TypeName())
  1540  }
  1541  
  1542  // GoType returns a string representing the type name, and the wire type
  1543  func (g *Generator) GoType(message *Descriptor, field *descriptor.FieldDescriptorProto) (typ string, wire string) {
  1544  	// TODO: Options.
  1545  	switch *field.Type {
  1546  	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
  1547  		typ, wire = "float64", "fixed64"
  1548  	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
  1549  		typ, wire = "float32", "fixed32"
  1550  	case descriptor.FieldDescriptorProto_TYPE_INT64:
  1551  		typ, wire = "int64", "varint"
  1552  	case descriptor.FieldDescriptorProto_TYPE_UINT64:
  1553  		typ, wire = "uint64", "varint"
  1554  	case descriptor.FieldDescriptorProto_TYPE_INT32:
  1555  		typ, wire = "int32", "varint"
  1556  	case descriptor.FieldDescriptorProto_TYPE_UINT32:
  1557  		typ, wire = "uint32", "varint"
  1558  	case descriptor.FieldDescriptorProto_TYPE_FIXED64:
  1559  		typ, wire = "uint64", "fixed64"
  1560  	case descriptor.FieldDescriptorProto_TYPE_FIXED32:
  1561  		typ, wire = "uint32", "fixed32"
  1562  	case descriptor.FieldDescriptorProto_TYPE_BOOL:
  1563  		typ, wire = "bool", "varint"
  1564  	case descriptor.FieldDescriptorProto_TYPE_STRING:
  1565  		typ, wire = "string", "bytes"
  1566  	case descriptor.FieldDescriptorProto_TYPE_GROUP:
  1567  		desc := g.ObjectNamed(field.GetTypeName())
  1568  		typ, wire = "*"+g.TypeName(desc), "group"
  1569  	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
  1570  		desc := g.ObjectNamed(field.GetTypeName())
  1571  		typ, wire = "*"+g.TypeName(desc), "bytes"
  1572  	case descriptor.FieldDescriptorProto_TYPE_BYTES:
  1573  		typ, wire = "[]byte", "bytes"
  1574  	case descriptor.FieldDescriptorProto_TYPE_ENUM:
  1575  		desc := g.ObjectNamed(field.GetTypeName())
  1576  		typ, wire = g.TypeName(desc), "varint"
  1577  	case descriptor.FieldDescriptorProto_TYPE_SFIXED32:
  1578  		typ, wire = "int32", "fixed32"
  1579  	case descriptor.FieldDescriptorProto_TYPE_SFIXED64:
  1580  		typ, wire = "int64", "fixed64"
  1581  	case descriptor.FieldDescriptorProto_TYPE_SINT32:
  1582  		typ, wire = "int32", "zigzag32"
  1583  	case descriptor.FieldDescriptorProto_TYPE_SINT64:
  1584  		typ, wire = "int64", "zigzag64"
  1585  	default:
  1586  		g.Fail("unknown type for", field.GetName())
  1587  	}
  1588  	if isRepeated(field) {
  1589  		typ = "[]" + typ
  1590  	} else if message != nil && message.proto3() {
  1591  		return
  1592  	} else if field.OneofIndex != nil && message != nil {
  1593  		return
  1594  	} else if needsStar(*field.Type) {
  1595  		typ = "*" + typ
  1596  	}
  1597  	return
  1598  }
  1599  
  1600  func (g *Generator) RecordTypeUse(t string) {
  1601  	if _, ok := g.typeNameToObject[t]; !ok {
  1602  		return
  1603  	}
  1604  	importPath := g.ObjectNamed(t).GoImportPath()
  1605  	if importPath == g.outputImportPath {
  1606  		// Don't record use of objects in our package.
  1607  		return
  1608  	}
  1609  	g.AddImport(importPath)
  1610  	g.usedPackages[importPath] = true
  1611  }
  1612  
  1613  // Method names that may be generated.  Fields with these names get an
  1614  // underscore appended. Any change to this set is a potential incompatible
  1615  // API change because it changes generated field names.
  1616  var methodNames = [...]string{
  1617  	"Reset",
  1618  	"String",
  1619  	"ProtoMessage",
  1620  	"Marshal",
  1621  	"Unmarshal",
  1622  	"ExtensionRangeArray",
  1623  	"ExtensionMap",
  1624  	"Descriptor",
  1625  }
  1626  
  1627  // Names of messages in the `google.protobuf` package for which
  1628  // we will generate XXX_WellKnownType methods.
  1629  var wellKnownTypes = map[string]bool{
  1630  	"Any":       true,
  1631  	"Duration":  true,
  1632  	"Empty":     true,
  1633  	"Struct":    true,
  1634  	"Timestamp": true,
  1635  
  1636  	"Value":       true,
  1637  	"ListValue":   true,
  1638  	"DoubleValue": true,
  1639  	"FloatValue":  true,
  1640  	"Int64Value":  true,
  1641  	"UInt64Value": true,
  1642  	"Int32Value":  true,
  1643  	"UInt32Value": true,
  1644  	"BoolValue":   true,
  1645  	"StringValue": true,
  1646  	"BytesValue":  true,
  1647  }
  1648  
  1649  // getterDefault finds the default value for the field to return from a getter,
  1650  // regardless of if it's a built in default or explicit from the source. Returns e.g. "nil", `""`, "Default_MessageType_FieldName"
  1651  func (g *Generator) getterDefault(field *descriptor.FieldDescriptorProto, goMessageType string) string {
  1652  	if isRepeated(field) {
  1653  		return "nil"
  1654  	}
  1655  	if def := field.GetDefaultValue(); def != "" {
  1656  		defaultConstant := g.defaultConstantName(goMessageType, field.GetName())
  1657  		if *field.Type != descriptor.FieldDescriptorProto_TYPE_BYTES {
  1658  			return defaultConstant
  1659  		}
  1660  		return "append([]byte(nil), " + defaultConstant + "...)"
  1661  	}
  1662  	switch *field.Type {
  1663  	case descriptor.FieldDescriptorProto_TYPE_BOOL:
  1664  		return "false"
  1665  	case descriptor.FieldDescriptorProto_TYPE_STRING:
  1666  		return `""`
  1667  	case descriptor.FieldDescriptorProto_TYPE_GROUP, descriptor.FieldDescriptorProto_TYPE_MESSAGE, descriptor.FieldDescriptorProto_TYPE_BYTES:
  1668  		return "nil"
  1669  	case descriptor.FieldDescriptorProto_TYPE_ENUM:
  1670  		obj := g.ObjectNamed(field.GetTypeName())
  1671  		var enum *EnumDescriptor
  1672  		if id, ok := obj.(*ImportedDescriptor); ok {
  1673  			// The enum type has been publicly imported.
  1674  			enum, _ = id.o.(*EnumDescriptor)
  1675  		} else {
  1676  			enum, _ = obj.(*EnumDescriptor)
  1677  		}
  1678  		if enum == nil {
  1679  			log.Printf("don't know how to generate getter for %s", field.GetName())
  1680  			return "nil"
  1681  		}
  1682  		if len(enum.Value) == 0 {
  1683  			return "0 // empty enum"
  1684  		}
  1685  		first := enum.Value[0].GetName()
  1686  		return g.DefaultPackageName(obj) + enum.prefix() + first
  1687  	default:
  1688  		return "0"
  1689  	}
  1690  }
  1691  
  1692  // defaultConstantName builds the name of the default constant from the message
  1693  // type name and the untouched field name, e.g. "Default_MessageType_FieldName"
  1694  func (g *Generator) defaultConstantName(goMessageType, protoFieldName string) string {
  1695  	return "Default_" + goMessageType + "_" + CamelCase(protoFieldName)
  1696  }
  1697  
  1698  // The different types of fields in a message and how to actually print them
  1699  // Most of the logic for generateMessage is in the methods of these types.
  1700  //
  1701  // Note that the content of the field is irrelevant, a simpleField can contain
  1702  // anything from a scalar to a group (which is just a message).
  1703  //
  1704  // Extension fields (and message sets) are however handled separately.
  1705  //
  1706  // simpleField - a field that is neiter weak nor oneof, possibly repeated
  1707  // oneofField - field containing list of subfields:
  1708  // - oneofSubField - a field within the oneof
  1709  
  1710  // msgCtx contains the context for the generator functions.
  1711  type msgCtx struct {
  1712  	goName  string      // Go struct name of the message, e.g. MessageName
  1713  	message *Descriptor // The descriptor for the message
  1714  }
  1715  
  1716  // fieldCommon contains data common to all types of fields.
  1717  type fieldCommon struct {
  1718  	goName     string // Go name of field, e.g. "FieldName" or "Descriptor_"
  1719  	protoName  string // Name of field in proto language, e.g. "field_name" or "descriptor"
  1720  	getterName string // Name of the getter, e.g. "GetFieldName" or "GetDescriptor_"
  1721  	goType     string // The Go type as a string, e.g. "*int32" or "*OtherMessage"
  1722  	tags       string // The tag string/annotation for the type, e.g. `protobuf:"varint,8,opt,name=region_id,json=regionId"`
  1723  	fullPath   string // The full path of the field as used by Annotate etc, e.g. "4,0,2,0"
  1724  }
  1725  
  1726  // getProtoName gets the proto name of a field, e.g. "field_name" or "descriptor".
  1727  func (f *fieldCommon) getProtoName() string {
  1728  	return f.protoName
  1729  }
  1730  
  1731  // getGoType returns the go type of the field  as a string, e.g. "*int32".
  1732  func (f *fieldCommon) getGoType() string {
  1733  	return f.goType
  1734  }
  1735  
  1736  // simpleField is not weak, not a oneof, not an extension. Can be required, optional or repeated.
  1737  type simpleField struct {
  1738  	fieldCommon
  1739  	protoTypeName string                               // Proto type name, empty if primitive, e.g. ".google.protobuf.Duration"
  1740  	protoType     descriptor.FieldDescriptorProto_Type // Actual type enum value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64
  1741  	deprecated    string                               // Deprecation comment, if any, e.g. "// Deprecated: Do not use."
  1742  	getterDef     string                               // Default for getters, e.g. "nil", `""` or "Default_MessageType_FieldName"
  1743  	protoDef      string                               // Default value as defined in the proto file, e.g "yoshi" or "5"
  1744  	comment       string                               // The full comment for the field, e.g. "// Useful information"
  1745  }
  1746  
  1747  // decl prints the declaration of the field in the struct (if any).
  1748  func (f *simpleField) decl(g *Generator, mc *msgCtx) {
  1749  	g.P(f.comment, Annotate(mc.message.file, f.fullPath, f.goName), "\t", f.goType, "\t`", f.tags, "`", f.deprecated)
  1750  }
  1751  
  1752  // getter prints the getter for the field.
  1753  func (f *simpleField) getter(g *Generator, mc *msgCtx) {
  1754  	star := ""
  1755  	tname := f.goType
  1756  	if needsStar(f.protoType) && tname[0] == '*' {
  1757  		tname = tname[1:]
  1758  		star = "*"
  1759  	}
  1760  	if f.deprecated != "" {
  1761  		g.P(f.deprecated)
  1762  	}
  1763  	g.P("func (m *", mc.goName, ") ", Annotate(mc.message.file, f.fullPath, f.getterName), "() "+tname+" {")
  1764  	if f.getterDef == "nil" { // Simpler getter
  1765  		g.P("if m != nil {")
  1766  		g.P("return m." + f.goName)
  1767  		g.P("}")
  1768  		g.P("return nil")
  1769  		g.P("}")
  1770  		g.P()
  1771  		return
  1772  	}
  1773  	if mc.message.proto3() {
  1774  		g.P("if m != nil {")
  1775  	} else {
  1776  		g.P("if m != nil && m." + f.goName + " != nil {")
  1777  	}
  1778  	g.P("return " + star + "m." + f.goName)
  1779  	g.P("}")
  1780  	g.P("return ", f.getterDef)
  1781  	g.P("}")
  1782  	g.P()
  1783  }
  1784  
  1785  // setter prints the setter method of the field.
  1786  func (f *simpleField) setter(g *Generator, mc *msgCtx) {
  1787  	// No setter for regular fields yet
  1788  }
  1789  
  1790  // getProtoDef returns the default value explicitly stated in the proto file, e.g "yoshi" or "5".
  1791  func (f *simpleField) getProtoDef() string {
  1792  	return f.protoDef
  1793  }
  1794  
  1795  // getProtoTypeName returns the protobuf type name for the field as returned by field.GetTypeName(), e.g. ".google.protobuf.Duration".
  1796  func (f *simpleField) getProtoTypeName() string {
  1797  	return f.protoTypeName
  1798  }
  1799  
  1800  // getProtoType returns the *field.Type value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64.
  1801  func (f *simpleField) getProtoType() descriptor.FieldDescriptorProto_Type {
  1802  	return f.protoType
  1803  }
  1804  
  1805  // oneofSubFields are kept slize held by each oneofField. They do not appear in the top level slize of fields for the message.
  1806  type oneofSubField struct {
  1807  	fieldCommon
  1808  	protoTypeName string                               // Proto type name, empty if primitive, e.g. ".google.protobuf.Duration"
  1809  	protoType     descriptor.FieldDescriptorProto_Type // Actual type enum value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64
  1810  	oneofTypeName string                               // Type name of the enclosing struct, e.g. "MessageName_FieldName"
  1811  	fieldNumber   int                                  // Actual field number, as defined in proto, e.g. 12
  1812  	getterDef     string                               // Default for getters, e.g. "nil", `""` or "Default_MessageType_FieldName"
  1813  	protoDef      string                               // Default value as defined in the proto file, e.g "yoshi" or "5"
  1814  	deprecated    string                               // Deprecation comment, if any.
  1815  }
  1816  
  1817  // typedNil prints a nil casted to the pointer to this field.
  1818  // - for XXX_OneofWrappers
  1819  func (f *oneofSubField) typedNil(g *Generator) {
  1820  	g.P("(*", f.oneofTypeName, ")(nil),")
  1821  }
  1822  
  1823  // getProtoDef returns the default value explicitly stated in the proto file, e.g "yoshi" or "5".
  1824  func (f *oneofSubField) getProtoDef() string {
  1825  	return f.protoDef
  1826  }
  1827  
  1828  // getProtoTypeName returns the protobuf type name for the field as returned by field.GetTypeName(), e.g. ".google.protobuf.Duration".
  1829  func (f *oneofSubField) getProtoTypeName() string {
  1830  	return f.protoTypeName
  1831  }
  1832  
  1833  // getProtoType returns the *field.Type value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64.
  1834  func (f *oneofSubField) getProtoType() descriptor.FieldDescriptorProto_Type {
  1835  	return f.protoType
  1836  }
  1837  
  1838  // oneofField represents the oneof on top level.
  1839  // The alternative fields within the oneof are represented by oneofSubField.
  1840  type oneofField struct {
  1841  	fieldCommon
  1842  	subFields []*oneofSubField // All the possible oneof fields
  1843  	comment   string           // The full comment for the field, e.g. "// Types that are valid to be assigned to MyOneof:\n\\"
  1844  }
  1845  
  1846  // decl prints the declaration of the field in the struct (if any).
  1847  func (f *oneofField) decl(g *Generator, mc *msgCtx) {
  1848  	comment := f.comment
  1849  	for _, sf := range f.subFields {
  1850  		comment += "//\t*" + sf.oneofTypeName + "\n"
  1851  	}
  1852  	g.P(comment, Annotate(mc.message.file, f.fullPath, f.goName), " ", f.goType, " `", f.tags, "`")
  1853  }
  1854  
  1855  // getter for a oneof field will print additional discriminators and interfaces for the oneof,
  1856  // also it prints all the getters for the sub fields.
  1857  func (f *oneofField) getter(g *Generator, mc *msgCtx) {
  1858  	// The discriminator type
  1859  	g.P("type ", f.goType, " interface {")
  1860  	g.P(f.goType, "()")
  1861  	g.P("}")
  1862  	g.P()
  1863  	// The subField types, fulfilling the discriminator type contract
  1864  	for _, sf := range f.subFields {
  1865  		g.P("type ", Annotate(mc.message.file, sf.fullPath, sf.oneofTypeName), " struct {")
  1866  		g.P(Annotate(mc.message.file, sf.fullPath, sf.goName), " ", sf.goType, " `", sf.tags, "`")
  1867  		g.P("}")
  1868  		g.P()
  1869  	}
  1870  	for _, sf := range f.subFields {
  1871  		g.P("func (*", sf.oneofTypeName, ") ", f.goType, "() {}")
  1872  		g.P()
  1873  	}
  1874  	// Getter for the oneof field
  1875  	g.P("func (m *", mc.goName, ") ", Annotate(mc.message.file, f.fullPath, f.getterName), "() ", f.goType, " {")
  1876  	g.P("if m != nil { return m.", f.goName, " }")
  1877  	g.P("return nil")
  1878  	g.P("}")
  1879  	g.P()
  1880  	// Getters for each oneof
  1881  	for _, sf := range f.subFields {
  1882  		if sf.deprecated != "" {
  1883  			g.P(sf.deprecated)
  1884  		}
  1885  		g.P("func (m *", mc.goName, ") ", Annotate(mc.message.file, sf.fullPath, sf.getterName), "() "+sf.goType+" {")
  1886  		g.P("if x, ok := m.", f.getterName, "().(*", sf.oneofTypeName, "); ok {")
  1887  		g.P("return x.", sf.goName)
  1888  		g.P("}")
  1889  		g.P("return ", sf.getterDef)
  1890  		g.P("}")
  1891  		g.P()
  1892  	}
  1893  }
  1894  
  1895  // setter prints the setter method of the field.
  1896  func (f *oneofField) setter(g *Generator, mc *msgCtx) {
  1897  	// No setters for oneof yet
  1898  }
  1899  
  1900  // topLevelField interface implemented by all types of fields on the top level (not oneofSubField).
  1901  type topLevelField interface {
  1902  	decl(g *Generator, mc *msgCtx)   // print declaration within the struct
  1903  	getter(g *Generator, mc *msgCtx) // print getter
  1904  	setter(g *Generator, mc *msgCtx) // print setter if applicable
  1905  }
  1906  
  1907  // defField interface implemented by all types of fields that can have defaults (not oneofField, but instead oneofSubField).
  1908  type defField interface {
  1909  	getProtoDef() string                                // default value explicitly stated in the proto file, e.g "yoshi" or "5"
  1910  	getProtoName() string                               // proto name of a field, e.g. "field_name" or "descriptor"
  1911  	getGoType() string                                  // go type of the field  as a string, e.g. "*int32"
  1912  	getProtoTypeName() string                           // protobuf type name for the field, e.g. ".google.protobuf.Duration"
  1913  	getProtoType() descriptor.FieldDescriptorProto_Type // *field.Type value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64
  1914  }
  1915  
  1916  // generateDefaultConstants adds constants for default values if needed, which is only if the default value is.
  1917  // explicit in the proto.
  1918  func (g *Generator) generateDefaultConstants(mc *msgCtx, topLevelFields []topLevelField) {
  1919  	// Collect fields that can have defaults
  1920  	dFields := []defField{}
  1921  	for _, pf := range topLevelFields {
  1922  		if f, ok := pf.(*oneofField); ok {
  1923  			for _, osf := range f.subFields {
  1924  				dFields = append(dFields, osf)
  1925  			}
  1926  			continue
  1927  		}
  1928  		dFields = append(dFields, pf.(defField))
  1929  	}
  1930  	for _, df := range dFields {
  1931  		def := df.getProtoDef()
  1932  		if def == "" {
  1933  			continue
  1934  		}
  1935  		fieldname := g.defaultConstantName(mc.goName, df.getProtoName())
  1936  		typename := df.getGoType()
  1937  		if typename[0] == '*' {
  1938  			typename = typename[1:]
  1939  		}
  1940  		kind := "const "
  1941  		switch {
  1942  		case typename == "bool":
  1943  		case typename == "string":
  1944  			def = strconv.Quote(def)
  1945  		case typename == "[]byte":
  1946  			def = "[]byte(" + strconv.Quote(unescape(def)) + ")"
  1947  			kind = "var "
  1948  		case def == "inf", def == "-inf", def == "nan":
  1949  			// These names are known to, and defined by, the protocol language.
  1950  			switch def {
  1951  			case "inf":
  1952  				def = "math.Inf(1)"
  1953  			case "-inf":
  1954  				def = "math.Inf(-1)"
  1955  			case "nan":
  1956  				def = "math.NaN()"
  1957  			}
  1958  			if df.getProtoType() == descriptor.FieldDescriptorProto_TYPE_FLOAT {
  1959  				def = "float32(" + def + ")"
  1960  			}
  1961  			kind = "var "
  1962  		case df.getProtoType() == descriptor.FieldDescriptorProto_TYPE_FLOAT:
  1963  			if f, err := strconv.ParseFloat(def, 32); err == nil {
  1964  				def = fmt.Sprint(float32(f))
  1965  			}
  1966  		case df.getProtoType() == descriptor.FieldDescriptorProto_TYPE_DOUBLE:
  1967  			if f, err := strconv.ParseFloat(def, 64); err == nil {
  1968  				def = fmt.Sprint(f)
  1969  			}
  1970  		case df.getProtoType() == descriptor.FieldDescriptorProto_TYPE_ENUM:
  1971  			// Must be an enum.  Need to construct the prefixed name.
  1972  			obj := g.ObjectNamed(df.getProtoTypeName())
  1973  			var enum *EnumDescriptor
  1974  			if id, ok := obj.(*ImportedDescriptor); ok {
  1975  				// The enum type has been publicly imported.
  1976  				enum, _ = id.o.(*EnumDescriptor)
  1977  			} else {
  1978  				enum, _ = obj.(*EnumDescriptor)
  1979  			}
  1980  			if enum == nil {
  1981  				log.Printf("don't know how to generate constant for %s", fieldname)
  1982  				continue
  1983  			}
  1984  			def = g.DefaultPackageName(obj) + enum.prefix() + def
  1985  		}
  1986  		g.P(kind, fieldname, " ", typename, " = ", def)
  1987  		g.file.addExport(mc.message, constOrVarSymbol{fieldname, kind, ""})
  1988  	}
  1989  	g.P()
  1990  }
  1991  
  1992  // generateInternalStructFields just adds the XXX_<something> fields to the message struct.
  1993  func (g *Generator) generateInternalStructFields(mc *msgCtx, topLevelFields []topLevelField) {
  1994  	g.P("XXX_NoUnkeyedLiteral\tstruct{} `json:\"-\"`") // prevent unkeyed struct literals
  1995  	if len(mc.message.ExtensionRange) > 0 {
  1996  		messageset := ""
  1997  		if opts := mc.message.Options; opts != nil && opts.GetMessageSetWireFormat() {
  1998  			messageset = "protobuf_messageset:\"1\" "
  1999  		}
  2000  		g.P(g.Pkg["proto"], ".XXX_InternalExtensions `", messageset, "json:\"-\"`")
  2001  	}
  2002  	g.P("XXX_unrecognized\t[]byte `json:\"-\"`")
  2003  	g.P("XXX_sizecache\tint32 `json:\"-\"`")
  2004  
  2005  }
  2006  
  2007  // generateOneofFuncs adds all the utility functions for oneof, including marshalling, unmarshalling and sizer.
  2008  func (g *Generator) generateOneofFuncs(mc *msgCtx, topLevelFields []topLevelField) {
  2009  	ofields := []*oneofField{}
  2010  	for _, f := range topLevelFields {
  2011  		if o, ok := f.(*oneofField); ok {
  2012  			ofields = append(ofields, o)
  2013  		}
  2014  	}
  2015  	if len(ofields) == 0 {
  2016  		return
  2017  	}
  2018  
  2019  	// OneofFuncs
  2020  	g.P("// XXX_OneofWrappers is for the internal use of the proto package.")
  2021  	g.P("func (*", mc.goName, ") XXX_OneofWrappers() []interface{} {")
  2022  	g.P("return []interface{}{")
  2023  	for _, of := range ofields {
  2024  		for _, sf := range of.subFields {
  2025  			sf.typedNil(g)
  2026  		}
  2027  	}
  2028  	g.P("}")
  2029  	g.P("}")
  2030  	g.P()
  2031  }
  2032  
  2033  // generateMessageStruct adds the actual struct with it's members (but not methods) to the output.
  2034  func (g *Generator) generateMessageStruct(mc *msgCtx, topLevelFields []topLevelField) {
  2035  	comments := g.PrintComments(mc.message.path)
  2036  
  2037  	// Guarantee deprecation comments appear after user-provided comments.
  2038  	if mc.message.GetOptions().GetDeprecated() {
  2039  		if comments {
  2040  			// Convention: Separate deprecation comments from original
  2041  			// comments with an empty line.
  2042  			g.P("//")
  2043  		}
  2044  		g.P(deprecationComment)
  2045  	}
  2046  
  2047  	g.P("type ", Annotate(mc.message.file, mc.message.path, mc.goName), " struct {")
  2048  	for _, pf := range topLevelFields {
  2049  		pf.decl(g, mc)
  2050  	}
  2051  	g.generateInternalStructFields(mc, topLevelFields)
  2052  	g.P("}")
  2053  }
  2054  
  2055  // generateGetters adds getters for all fields, including oneofs and weak fields when applicable.
  2056  func (g *Generator) generateGetters(mc *msgCtx, topLevelFields []topLevelField) {
  2057  	for _, pf := range topLevelFields {
  2058  		pf.getter(g, mc)
  2059  	}
  2060  }
  2061  
  2062  // generateSetters add setters for all fields, including oneofs and weak fields when applicable.
  2063  func (g *Generator) generateSetters(mc *msgCtx, topLevelFields []topLevelField) {
  2064  	for _, pf := range topLevelFields {
  2065  		pf.setter(g, mc)
  2066  	}
  2067  }
  2068  
  2069  // generateCommonMethods adds methods to the message that are not on a per field basis.
  2070  func (g *Generator) generateCommonMethods(mc *msgCtx) {
  2071  	// Reset, String and ProtoMessage methods.
  2072  	g.P("func (m *", mc.goName, ") Reset() { *m = ", mc.goName, "{} }")
  2073  	g.P("func (m *", mc.goName, ") String() string { return ", g.Pkg["proto"], ".CompactTextString(m) }")
  2074  	g.P("func (*", mc.goName, ") ProtoMessage() {}")
  2075  	var indexes []string
  2076  	for m := mc.message; m != nil; m = m.parent {
  2077  		indexes = append([]string{strconv.Itoa(m.index)}, indexes...)
  2078  	}
  2079  	g.P("func (*", mc.goName, ") Descriptor() ([]byte, []int) {")
  2080  	g.P("return ", g.file.VarName(), ", []int{", strings.Join(indexes, ", "), "}")
  2081  	g.P("}")
  2082  	g.P()
  2083  	// TODO: Revisit the decision to use a XXX_WellKnownType method
  2084  	// if we change proto.MessageName to work with multiple equivalents.
  2085  	if mc.message.file.GetPackage() == "google.protobuf" && wellKnownTypes[mc.message.GetName()] {
  2086  		g.P("func (*", mc.goName, `) XXX_WellKnownType() string { return "`, mc.message.GetName(), `" }`)
  2087  		g.P()
  2088  	}
  2089  
  2090  	// Extension support methods
  2091  	if len(mc.message.ExtensionRange) > 0 {
  2092  		g.P()
  2093  		g.P("var extRange_", mc.goName, " = []", g.Pkg["proto"], ".ExtensionRange{")
  2094  		for _, r := range mc.message.ExtensionRange {
  2095  			end := fmt.Sprint(*r.End - 1) // make range inclusive on both ends
  2096  			g.P("{Start: ", r.Start, ", End: ", end, "},")
  2097  		}
  2098  		g.P("}")
  2099  		g.P("func (*", mc.goName, ") ExtensionRangeArray() []", g.Pkg["proto"], ".ExtensionRange {")
  2100  		g.P("return extRange_", mc.goName)
  2101  		g.P("}")
  2102  		g.P()
  2103  	}
  2104  
  2105  	// TODO: It does not scale to keep adding another method for every
  2106  	// operation on protos that we want to switch over to using the
  2107  	// table-driven approach. Instead, we should only add a single method
  2108  	// that allows getting access to the *InternalMessageInfo struct and then
  2109  	// calling Unmarshal, Marshal, Merge, Size, and Discard directly on that.
  2110  
  2111  	// Wrapper for table-driven marshaling and unmarshaling.
  2112  	g.P("func (m *", mc.goName, ") XXX_Unmarshal(b []byte) error {")
  2113  	g.P("return xxx_messageInfo_", mc.goName, ".Unmarshal(m, b)")
  2114  	g.P("}")
  2115  
  2116  	g.P("func (m *", mc.goName, ") XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {")
  2117  	g.P("return xxx_messageInfo_", mc.goName, ".Marshal(b, m, deterministic)")
  2118  	g.P("}")
  2119  
  2120  	g.P("func (m *", mc.goName, ") XXX_Merge(src ", g.Pkg["proto"], ".Message) {")
  2121  	g.P("xxx_messageInfo_", mc.goName, ".Merge(m, src)")
  2122  	g.P("}")
  2123  
  2124  	g.P("func (m *", mc.goName, ") XXX_Size() int {") // avoid name clash with "Size" field in some message
  2125  	g.P("return xxx_messageInfo_", mc.goName, ".Size(m)")
  2126  	g.P("}")
  2127  
  2128  	g.P("func (m *", mc.goName, ") XXX_DiscardUnknown() {")
  2129  	g.P("xxx_messageInfo_", mc.goName, ".DiscardUnknown(m)")
  2130  	g.P("}")
  2131  
  2132  	g.P("var xxx_messageInfo_", mc.goName, " ", g.Pkg["proto"], ".InternalMessageInfo")
  2133  	g.P()
  2134  }
  2135  
  2136  // Generate the type, methods and default constant definitions for this Descriptor.
  2137  func (g *Generator) generateMessage(message *Descriptor) {
  2138  	topLevelFields := []topLevelField{}
  2139  	oFields := make(map[int32]*oneofField)
  2140  	// The full type name
  2141  	typeName := message.TypeName()
  2142  	// The full type name, CamelCased.
  2143  	goTypeName := CamelCaseSlice(typeName)
  2144  
  2145  	usedNames := make(map[string]bool)
  2146  	for _, n := range methodNames {
  2147  		usedNames[n] = true
  2148  	}
  2149  
  2150  	// allocNames finds a conflict-free variation of the given strings,
  2151  	// consistently mutating their suffixes.
  2152  	// It returns the same number of strings.
  2153  	allocNames := func(ns ...string) []string {
  2154  	Loop:
  2155  		for {
  2156  			for _, n := range ns {
  2157  				if usedNames[n] {
  2158  					for i := range ns {
  2159  						ns[i] += "_"
  2160  					}
  2161  					continue Loop
  2162  				}
  2163  			}
  2164  			for _, n := range ns {
  2165  				usedNames[n] = true
  2166  			}
  2167  			return ns
  2168  		}
  2169  	}
  2170  
  2171  	mapFieldTypes := make(map[*descriptor.FieldDescriptorProto]string) // keep track of the map fields to be added later
  2172  
  2173  	// Build a structure more suitable for generating the text in one pass
  2174  	for i, field := range message.Field {
  2175  		// Allocate the getter and the field at the same time so name
  2176  		// collisions create field/method consistent names.
  2177  		// TODO: This allocation occurs based on the order of the fields
  2178  		// in the proto file, meaning that a change in the field
  2179  		// ordering can change generated Method/Field names.
  2180  		base := CamelCase(*field.Name)
  2181  		ns := allocNames(base, "Get"+base)
  2182  		fieldName, fieldGetterName := ns[0], ns[1]
  2183  		typename, wiretype := g.GoType(message, field)
  2184  		jsonName := *field.Name
  2185  		tag := fmt.Sprintf("protobuf:%s json:%q", g.goTag(message, field, wiretype), jsonName+",omitempty")
  2186  
  2187  		oneof := field.OneofIndex != nil
  2188  		if oneof && oFields[*field.OneofIndex] == nil {
  2189  			odp := message.OneofDecl[int(*field.OneofIndex)]
  2190  			base := CamelCase(odp.GetName())
  2191  			fname := allocNames(base)[0]
  2192  
  2193  			// This is the first field of a oneof we haven't seen before.
  2194  			// Generate the union field.
  2195  			oneofFullPath := fmt.Sprintf("%s,%d,%d", message.path, messageOneofPath, *field.OneofIndex)
  2196  			c, ok := g.makeComments(oneofFullPath)
  2197  			if ok {
  2198  				c += "\n//\n"
  2199  			}
  2200  			c += "// Types that are valid to be assigned to " + fname + ":\n"
  2201  			// Generate the rest of this comment later,
  2202  			// when we've computed any disambiguation.
  2203  
  2204  			dname := "is" + goTypeName + "_" + fname
  2205  			tag := `protobuf_oneof:"` + odp.GetName() + `"`
  2206  			of := oneofField{
  2207  				fieldCommon: fieldCommon{
  2208  					goName:     fname,
  2209  					getterName: "Get" + fname,
  2210  					goType:     dname,
  2211  					tags:       tag,
  2212  					protoName:  odp.GetName(),
  2213  					fullPath:   oneofFullPath,
  2214  				},
  2215  				comment: c,
  2216  			}
  2217  			topLevelFields = append(topLevelFields, &of)
  2218  			oFields[*field.OneofIndex] = &of
  2219  		}
  2220  
  2221  		if *field.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE {
  2222  			desc := g.ObjectNamed(field.GetTypeName())
  2223  			if d, ok := desc.(*Descriptor); ok && d.GetOptions().GetMapEntry() {
  2224  				// Figure out the Go types and tags for the key and value types.
  2225  				keyField, valField := d.Field[0], d.Field[1]
  2226  				keyType, keyWire := g.GoType(d, keyField)
  2227  				valType, valWire := g.GoType(d, valField)
  2228  				keyTag, valTag := g.goTag(d, keyField, keyWire), g.goTag(d, valField, valWire)
  2229  
  2230  				// We don't use stars, except for message-typed values.
  2231  				// Message and enum types are the only two possibly foreign types used in maps,
  2232  				// so record their use. They are not permitted as map keys.
  2233  				keyType = strings.TrimPrefix(keyType, "*")
  2234  				switch *valField.Type {
  2235  				case descriptor.FieldDescriptorProto_TYPE_ENUM:
  2236  					valType = strings.TrimPrefix(valType, "*")
  2237  					g.RecordTypeUse(valField.GetTypeName())
  2238  				case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
  2239  					g.RecordTypeUse(valField.GetTypeName())
  2240  				default:
  2241  					valType = strings.TrimPrefix(valType, "*")
  2242  				}
  2243  
  2244  				typename = fmt.Sprintf("map[%s]%s", keyType, valType)
  2245  				mapFieldTypes[field] = typename // record for the getter generation
  2246  
  2247  				tag += fmt.Sprintf(" protobuf_key:%s protobuf_val:%s", keyTag, valTag)
  2248  			}
  2249  		}
  2250  
  2251  		fieldDeprecated := ""
  2252  		if field.GetOptions().GetDeprecated() {
  2253  			fieldDeprecated = deprecationComment
  2254  		}
  2255  
  2256  		dvalue := g.getterDefault(field, goTypeName)
  2257  		if oneof {
  2258  			tname := goTypeName + "_" + fieldName
  2259  			// It is possible for this to collide with a message or enum
  2260  			// nested in this message. Check for collisions.
  2261  			for {
  2262  				ok := true
  2263  				for _, desc := range message.nested {
  2264  					if CamelCaseSlice(desc.TypeName()) == tname {
  2265  						ok = false
  2266  						break
  2267  					}
  2268  				}
  2269  				for _, enum := range message.enums {
  2270  					if CamelCaseSlice(enum.TypeName()) == tname {
  2271  						ok = false
  2272  						break
  2273  					}
  2274  				}
  2275  				if !ok {
  2276  					tname += "_"
  2277  					continue
  2278  				}
  2279  				break
  2280  			}
  2281  
  2282  			oneofField := oFields[*field.OneofIndex]
  2283  			tag := "protobuf:" + g.goTag(message, field, wiretype)
  2284  			sf := oneofSubField{
  2285  				fieldCommon: fieldCommon{
  2286  					goName:     fieldName,
  2287  					getterName: fieldGetterName,
  2288  					goType:     typename,
  2289  					tags:       tag,
  2290  					protoName:  field.GetName(),
  2291  					fullPath:   fmt.Sprintf("%s,%d,%d", message.path, messageFieldPath, i),
  2292  				},
  2293  				protoTypeName: field.GetTypeName(),
  2294  				fieldNumber:   int(*field.Number),
  2295  				protoType:     *field.Type,
  2296  				getterDef:     dvalue,
  2297  				protoDef:      field.GetDefaultValue(),
  2298  				oneofTypeName: tname,
  2299  				deprecated:    fieldDeprecated,
  2300  			}
  2301  			oneofField.subFields = append(oneofField.subFields, &sf)
  2302  			g.RecordTypeUse(field.GetTypeName())
  2303  			continue
  2304  		}
  2305  
  2306  		fieldFullPath := fmt.Sprintf("%s,%d,%d", message.path, messageFieldPath, i)
  2307  		c, ok := g.makeComments(fieldFullPath)
  2308  		if ok {
  2309  			c += "\n"
  2310  		}
  2311  		rf := simpleField{
  2312  			fieldCommon: fieldCommon{
  2313  				goName:     fieldName,
  2314  				getterName: fieldGetterName,
  2315  				goType:     typename,
  2316  				tags:       tag,
  2317  				protoName:  field.GetName(),
  2318  				fullPath:   fieldFullPath,
  2319  			},
  2320  			protoTypeName: field.GetTypeName(),
  2321  			protoType:     *field.Type,
  2322  			deprecated:    fieldDeprecated,
  2323  			getterDef:     dvalue,
  2324  			protoDef:      field.GetDefaultValue(),
  2325  			comment:       c,
  2326  		}
  2327  		var pf topLevelField = &rf
  2328  
  2329  		topLevelFields = append(topLevelFields, pf)
  2330  		g.RecordTypeUse(field.GetTypeName())
  2331  	}
  2332  
  2333  	mc := &msgCtx{
  2334  		goName:  goTypeName,
  2335  		message: message,
  2336  	}
  2337  
  2338  	g.generateMessageStruct(mc, topLevelFields)
  2339  	g.P()
  2340  	g.generateCommonMethods(mc)
  2341  	g.P()
  2342  	g.generateDefaultConstants(mc, topLevelFields)
  2343  	g.P()
  2344  	g.generateGetters(mc, topLevelFields)
  2345  	g.P()
  2346  	g.generateSetters(mc, topLevelFields)
  2347  	g.P()
  2348  	g.generateOneofFuncs(mc, topLevelFields)
  2349  	g.P()
  2350  
  2351  	var oneofTypes []string
  2352  	for _, f := range topLevelFields {
  2353  		if of, ok := f.(*oneofField); ok {
  2354  			for _, osf := range of.subFields {
  2355  				oneofTypes = append(oneofTypes, osf.oneofTypeName)
  2356  			}
  2357  		}
  2358  	}
  2359  
  2360  	opts := message.Options
  2361  	ms := &messageSymbol{
  2362  		sym:           goTypeName,
  2363  		hasExtensions: len(message.ExtensionRange) > 0,
  2364  		isMessageSet:  opts != nil && opts.GetMessageSetWireFormat(),
  2365  		oneofTypes:    oneofTypes,
  2366  	}
  2367  	g.file.addExport(message, ms)
  2368  
  2369  	for _, ext := range message.ext {
  2370  		g.generateExtension(ext)
  2371  	}
  2372  
  2373  	fullName := strings.Join(message.TypeName(), ".")
  2374  	if g.file.Package != nil {
  2375  		fullName = *g.file.Package + "." + fullName
  2376  	}
  2377  
  2378  	g.addInitf("%s.RegisterType((*%s)(nil), %q)", g.Pkg["proto"], goTypeName, fullName)
  2379  	// Register types for native map types.
  2380  	for _, k := range mapFieldKeys(mapFieldTypes) {
  2381  		fullName := strings.TrimPrefix(*k.TypeName, ".")
  2382  		g.addInitf("%s.RegisterMapType((%s)(nil), %q)", g.Pkg["proto"], mapFieldTypes[k], fullName)
  2383  	}
  2384  
  2385  }
  2386  
  2387  type byTypeName []*descriptor.FieldDescriptorProto
  2388  
  2389  func (a byTypeName) Len() int           { return len(a) }
  2390  func (a byTypeName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
  2391  func (a byTypeName) Less(i, j int) bool { return *a[i].TypeName < *a[j].TypeName }
  2392  
  2393  // mapFieldKeys returns the keys of m in a consistent order.
  2394  func mapFieldKeys(m map[*descriptor.FieldDescriptorProto]string) []*descriptor.FieldDescriptorProto {
  2395  	keys := make([]*descriptor.FieldDescriptorProto, 0, len(m))
  2396  	for k := range m {
  2397  		keys = append(keys, k)
  2398  	}
  2399  	sort.Sort(byTypeName(keys))
  2400  	return keys
  2401  }
  2402  
  2403  var escapeChars = [256]byte{
  2404  	'a': '\a', 'b': '\b', 'f': '\f', 'n': '\n', 'r': '\r', 't': '\t', 'v': '\v', '\\': '\\', '"': '"', '\'': '\'', '?': '?',
  2405  }
  2406  
  2407  // unescape reverses the "C" escaping that protoc does for default values of bytes fields.
  2408  // It is best effort in that it effectively ignores malformed input. Seemingly invalid escape
  2409  // sequences are conveyed, unmodified, into the decoded result.
  2410  func unescape(s string) string {
  2411  	// NB: Sadly, we can't use strconv.Unquote because protoc will escape both
  2412  	// single and double quotes, but strconv.Unquote only allows one or the
  2413  	// other (based on actual surrounding quotes of its input argument).
  2414  
  2415  	var out []byte
  2416  	for len(s) > 0 {
  2417  		// regular character, or too short to be valid escape
  2418  		if s[0] != '\\' || len(s) < 2 {
  2419  			out = append(out, s[0])
  2420  			s = s[1:]
  2421  		} else if c := escapeChars[s[1]]; c != 0 {
  2422  			// escape sequence
  2423  			out = append(out, c)
  2424  			s = s[2:]
  2425  		} else if s[1] == 'x' || s[1] == 'X' {
  2426  			// hex escape, e.g. "\x80
  2427  			if len(s) < 4 {
  2428  				// too short to be valid
  2429  				out = append(out, s[:2]...)
  2430  				s = s[2:]
  2431  				continue
  2432  			}
  2433  			v, err := strconv.ParseUint(s[2:4], 16, 8)
  2434  			if err != nil {
  2435  				out = append(out, s[:4]...)
  2436  			} else {
  2437  				out = append(out, byte(v))
  2438  			}
  2439  			s = s[4:]
  2440  		} else if '0' <= s[1] && s[1] <= '7' {
  2441  			// octal escape, can vary from 1 to 3 octal digits; e.g., "\0" "\40" or "\164"
  2442  			// so consume up to 2 more bytes or up to end-of-string
  2443  			n := len(s[1:]) - len(strings.TrimLeft(s[1:], "01234567"))
  2444  			if n > 3 {
  2445  				n = 3
  2446  			}
  2447  			v, err := strconv.ParseUint(s[1:1+n], 8, 8)
  2448  			if err != nil {
  2449  				out = append(out, s[:1+n]...)
  2450  			} else {
  2451  				out = append(out, byte(v))
  2452  			}
  2453  			s = s[1+n:]
  2454  		} else {
  2455  			// bad escape, just propagate the slash as-is
  2456  			out = append(out, s[0])
  2457  			s = s[1:]
  2458  		}
  2459  	}
  2460  
  2461  	return string(out)
  2462  }
  2463  
  2464  func (g *Generator) generateExtension(ext *ExtensionDescriptor) {
  2465  	ccTypeName := ext.DescName()
  2466  
  2467  	extObj := g.ObjectNamed(*ext.Extendee)
  2468  	var extDesc *Descriptor
  2469  	if id, ok := extObj.(*ImportedDescriptor); ok {
  2470  		// This is extending a publicly imported message.
  2471  		// We need the underlying type for goTag.
  2472  		extDesc = id.o.(*Descriptor)
  2473  	} else {
  2474  		extDesc = extObj.(*Descriptor)
  2475  	}
  2476  	extendedType := "*" + g.TypeName(extObj) // always use the original
  2477  	field := ext.FieldDescriptorProto
  2478  	fieldType, wireType := g.GoType(ext.parent, field)
  2479  	tag := g.goTag(extDesc, field, wireType)
  2480  	g.RecordTypeUse(*ext.Extendee)
  2481  	if n := ext.FieldDescriptorProto.TypeName; n != nil {
  2482  		// foreign extension type
  2483  		g.RecordTypeUse(*n)
  2484  	}
  2485  
  2486  	typeName := ext.TypeName()
  2487  
  2488  	// Special case for proto2 message sets: If this extension is extending
  2489  	// proto2.bridge.MessageSet, and its final name component is "message_set_extension",
  2490  	// then drop that last component.
  2491  	//
  2492  	// TODO: This should be implemented in the text formatter rather than the generator.
  2493  	// In addition, the situation for when to apply this special case is implemented
  2494  	// differently in other languages:
  2495  	// https://github.com/google/protobuf/blob/aff10976/src/google/protobuf/text_format.cc#L1560
  2496  	if extDesc.GetOptions().GetMessageSetWireFormat() && typeName[len(typeName)-1] == "message_set_extension" {
  2497  		typeName = typeName[:len(typeName)-1]
  2498  	}
  2499  
  2500  	// For text formatting, the package must be exactly what the .proto file declares,
  2501  	// ignoring overrides such as the go_package option, and with no dot/underscore mapping.
  2502  	extName := strings.Join(typeName, ".")
  2503  	if g.file.Package != nil {
  2504  		extName = *g.file.Package + "." + extName
  2505  	}
  2506  
  2507  	g.P("var ", ccTypeName, " = &", g.Pkg["proto"], ".ExtensionDesc{")
  2508  	g.P("ExtendedType: (", extendedType, ")(nil),")
  2509  	g.P("ExtensionType: (", fieldType, ")(nil),")
  2510  	g.P("Field: ", field.Number, ",")
  2511  	g.P(`Name: "`, extName, `",`)
  2512  	g.P("Tag: ", tag, ",")
  2513  	g.P(`Filename: "`, g.file.GetName(), `",`)
  2514  
  2515  	g.P("}")
  2516  	g.P()
  2517  
  2518  	g.addInitf("%s.RegisterExtension(%s)", g.Pkg["proto"], ext.DescName())
  2519  
  2520  	g.file.addExport(ext, constOrVarSymbol{ccTypeName, "var", ""})
  2521  }
  2522  
  2523  func (g *Generator) generateInitFunction() {
  2524  	if len(g.init) == 0 {
  2525  		return
  2526  	}
  2527  	g.P("func init() {")
  2528  	for _, l := range g.init {
  2529  		g.P(l)
  2530  	}
  2531  	g.P("}")
  2532  	g.init = nil
  2533  }
  2534  
  2535  func (g *Generator) generateFileDescriptor(file *FileDescriptor) {
  2536  	// Make a copy and trim source_code_info data.
  2537  	// TODO: Trim this more when we know exactly what we need.
  2538  	pb := proto.Clone(file.FileDescriptorProto).(*descriptor.FileDescriptorProto)
  2539  	pb.SourceCodeInfo = nil
  2540  
  2541  	b, err := proto.Marshal(pb)
  2542  	if err != nil {
  2543  		g.Fail(err.Error())
  2544  	}
  2545  
  2546  	var buf bytes.Buffer
  2547  	w, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression)
  2548  	w.Write(b)
  2549  	w.Close()
  2550  	b = buf.Bytes()
  2551  
  2552  	v := file.VarName()
  2553  	g.P()
  2554  	g.P("func init() { ", g.Pkg["proto"], ".RegisterFile(", strconv.Quote(*file.Name), ", ", v, ") }")
  2555  	g.P("var ", v, " = []byte{")
  2556  	g.P("// ", len(b), " bytes of a gzipped FileDescriptorProto")
  2557  	for len(b) > 0 {
  2558  		n := 16
  2559  		if n > len(b) {
  2560  			n = len(b)
  2561  		}
  2562  
  2563  		s := ""
  2564  		for _, c := range b[:n] {
  2565  			s += fmt.Sprintf("0x%02x,", c)
  2566  		}
  2567  		g.P(s)
  2568  
  2569  		b = b[n:]
  2570  	}
  2571  	g.P("}")
  2572  }
  2573  
  2574  func (g *Generator) generateEnumRegistration(enum *EnumDescriptor) {
  2575  	// // We always print the full (proto-world) package name here.
  2576  	pkg := enum.File().GetPackage()
  2577  	if pkg != "" {
  2578  		pkg += "."
  2579  	}
  2580  	// The full type name
  2581  	typeName := enum.TypeName()
  2582  	// The full type name, CamelCased.
  2583  	ccTypeName := CamelCaseSlice(typeName)
  2584  	g.addInitf("%s.RegisterEnum(%q, %[3]s_name, %[3]s_value)", g.Pkg["proto"], pkg+ccTypeName, ccTypeName)
  2585  }
  2586  
  2587  // And now lots of helper functions.
  2588  
  2589  // Is c an ASCII lower-case letter?
  2590  func isASCIILower(c byte) bool {
  2591  	return 'a' <= c && c <= 'z'
  2592  }
  2593  
  2594  // Is c an ASCII digit?
  2595  func isASCIIDigit(c byte) bool {
  2596  	return '0' <= c && c <= '9'
  2597  }
  2598  
  2599  // CamelCase returns the CamelCased name.
  2600  // If there is an interior underscore followed by a lower case letter,
  2601  // drop the underscore and convert the letter to upper case.
  2602  // There is a remote possibility of this rewrite causing a name collision,
  2603  // but it's so remote we're prepared to pretend it's nonexistent - since the
  2604  // C++ generator lowercases names, it's extremely unlikely to have two fields
  2605  // with different capitalizations.
  2606  // In short, _my_field_name_2 becomes XMyFieldName_2.
  2607  func CamelCase(s string) string {
  2608  	if s == "" {
  2609  		return ""
  2610  	}
  2611  	t := make([]byte, 0, 32)
  2612  	i := 0
  2613  	if s[0] == '_' {
  2614  		// Need a capital letter; drop the '_'.
  2615  		t = append(t, 'X')
  2616  		i++
  2617  	}
  2618  	// Invariant: if the next letter is lower case, it must be converted
  2619  	// to upper case.
  2620  	// That is, we process a word at a time, where words are marked by _ or
  2621  	// upper case letter. Digits are treated as words.
  2622  	for ; i < len(s); i++ {
  2623  		c := s[i]
  2624  		if c == '_' && i+1 < len(s) && isASCIILower(s[i+1]) {
  2625  			continue // Skip the underscore in s.
  2626  		}
  2627  		if isASCIIDigit(c) {
  2628  			t = append(t, c)
  2629  			continue
  2630  		}
  2631  		// Assume we have a letter now - if not, it's a bogus identifier.
  2632  		// The next word is a sequence of characters that must start upper case.
  2633  		if isASCIILower(c) {
  2634  			c ^= ' ' // Make it a capital letter.
  2635  		}
  2636  		t = append(t, c) // Guaranteed not lower case.
  2637  		// Accept lower case sequence that follows.
  2638  		for i+1 < len(s) && isASCIILower(s[i+1]) {
  2639  			i++
  2640  			t = append(t, s[i])
  2641  		}
  2642  	}
  2643  	return string(t)
  2644  }
  2645  
  2646  // CamelCaseSlice is like CamelCase, but the argument is a slice of strings to
  2647  // be joined with "_".
  2648  func CamelCaseSlice(elem []string) string { return CamelCase(strings.Join(elem, "_")) }
  2649  
  2650  // dottedSlice turns a sliced name into a dotted name.
  2651  func dottedSlice(elem []string) string { return strings.Join(elem, ".") }
  2652  
  2653  // Is this field optional?
  2654  func isOptional(field *descriptor.FieldDescriptorProto) bool {
  2655  	return *field.Proto3Optional
  2656  }
  2657  
  2658  // Is this field required?
  2659  func isRequired(field *descriptor.FieldDescriptorProto) bool {
  2660  	return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REQUIRED
  2661  }
  2662  
  2663  // Is this field repeated?
  2664  func isRepeated(field *descriptor.FieldDescriptorProto) bool {
  2665  	return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED
  2666  }
  2667  
  2668  // Is this field a scalar numeric type?
  2669  func isScalar(field *descriptor.FieldDescriptorProto) bool {
  2670  	if field.Type == nil {
  2671  		return false
  2672  	}
  2673  	switch *field.Type {
  2674  	case descriptor.FieldDescriptorProto_TYPE_DOUBLE,
  2675  		descriptor.FieldDescriptorProto_TYPE_FLOAT,
  2676  		descriptor.FieldDescriptorProto_TYPE_INT64,
  2677  		descriptor.FieldDescriptorProto_TYPE_UINT64,
  2678  		descriptor.FieldDescriptorProto_TYPE_INT32,
  2679  		descriptor.FieldDescriptorProto_TYPE_FIXED64,
  2680  		descriptor.FieldDescriptorProto_TYPE_FIXED32,
  2681  		descriptor.FieldDescriptorProto_TYPE_BOOL,
  2682  		descriptor.FieldDescriptorProto_TYPE_UINT32,
  2683  		descriptor.FieldDescriptorProto_TYPE_ENUM,
  2684  		descriptor.FieldDescriptorProto_TYPE_SFIXED32,
  2685  		descriptor.FieldDescriptorProto_TYPE_SFIXED64,
  2686  		descriptor.FieldDescriptorProto_TYPE_SINT32,
  2687  		descriptor.FieldDescriptorProto_TYPE_SINT64:
  2688  		return true
  2689  	default:
  2690  		return false
  2691  	}
  2692  }
  2693  
  2694  // badToUnderscore is the mapping function used to generate Go names from package names,
  2695  // which can be dotted in the input .proto file.  It replaces non-identifier characters such as
  2696  // dot or dash with underscore.
  2697  func badToUnderscore(r rune) rune {
  2698  	if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' {
  2699  		return r
  2700  	}
  2701  	return '_'
  2702  }
  2703  
  2704  // baseName returns the last path element of the name, with the last dotted suffix removed.
  2705  func baseName(name string) string {
  2706  	// First, find the last element
  2707  	if i := strings.LastIndex(name, "/"); i >= 0 {
  2708  		name = name[i+1:]
  2709  	}
  2710  	// Now drop the suffix
  2711  	if i := strings.LastIndex(name, "."); i >= 0 {
  2712  		name = name[0:i]
  2713  	}
  2714  	return name
  2715  }
  2716  
  2717  // The SourceCodeInfo message describes the location of elements of a parsed
  2718  // .proto file by way of a "path", which is a sequence of integers that
  2719  // describe the route from a FileDescriptorProto to the relevant submessage.
  2720  // The path alternates between a field number of a repeated field, and an index
  2721  // into that repeated field. The constants below define the field numbers that
  2722  // are used.
  2723  //
  2724  // See descriptor.proto for more information about this.
  2725  const (
  2726  	// tag numbers in FileDescriptorProto
  2727  	packagePath = 2 // package
  2728  	messagePath = 4 // message_type
  2729  	enumPath    = 5 // enum_type
  2730  	// tag numbers in DescriptorProto
  2731  	messageFieldPath   = 2 // field
  2732  	messageMessagePath = 3 // nested_type
  2733  	messageEnumPath    = 4 // enum_type
  2734  	messageOneofPath   = 8 // oneof_decl
  2735  	// tag numbers in EnumDescriptorProto
  2736  	enumValuePath = 2 // value
  2737  )
  2738  
  2739  var supportTypeAliases bool
  2740  
  2741  func init() {
  2742  	for _, tag := range build.Default.ReleaseTags {
  2743  		if tag == "go1.9" {
  2744  			supportTypeAliases = true
  2745  			return
  2746  		}
  2747  	}
  2748  }