gitee.com/sasukebo/go-micro/v4@v4.7.1/cmd/protoc-gen-micro/generator/generator.go (about)

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