...

Source file src/github.com/golang/protobuf/protoc-gen-go/generator/generator.go

Documentation: github.com/golang/protobuf/protoc-gen-go/generator

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

View as plain text