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