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