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