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