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. DO NOT EDIT.")
1241	g.P("// source: ", g.file.Name)
1242	g.P()
1243
1244	name := g.file.PackageName()
1245
1246	if g.file.index == 0 {
1247		// Generate package docs for the first file in the package.
1248		g.P("/*")
1249		g.P("Package ", name, " is a generated protocol buffer package.")
1250		g.P()
1251		if loc, ok := g.file.comments[strconv.Itoa(packagePath)]; ok {
1252			// not using g.PrintComments because this is a /* */ comment block.
1253			text := strings.TrimSuffix(loc.GetLeadingComments(), "\n")
1254			for _, line := range strings.Split(text, "\n") {
1255				line = strings.TrimPrefix(line, " ")
1256				// ensure we don't escape from the block comment
1257				line = strings.Replace(line, "*/", "* /", -1)
1258				g.P(line)
1259			}
1260			g.P()
1261		}
1262		var topMsgs []string
1263		g.P("It is generated from these files:")
1264		for _, f := range g.genFiles {
1265			g.P("\t", f.Name)
1266			for _, msg := range f.desc {
1267				if msg.parent != nil {
1268					continue
1269				}
1270				topMsgs = append(topMsgs, CamelCaseSlice(msg.TypeName()))
1271			}
1272		}
1273		g.P()
1274		g.P("It has these top-level messages:")
1275		for _, msg := range topMsgs {
1276			g.P("\t", msg)
1277		}
1278		g.P("*/")
1279	}
1280
1281	g.P("package ", name)
1282	g.P()
1283}
1284
1285// PrintComments prints any comments from the source .proto file.
1286// The path is a comma-separated list of integers.
1287// It returns an indication of whether any comments were printed.
1288// See descriptor.proto for its format.
1289func (g *Generator) PrintComments(path string) bool {
1290	if !g.writeOutput {
1291		return false
1292	}
1293	if loc, ok := g.file.comments[path]; ok {
1294		text := strings.TrimSuffix(loc.GetLeadingComments(), "\n")
1295		for _, line := range strings.Split(text, "\n") {
1296			g.P("// ", strings.TrimPrefix(line, " "))
1297		}
1298		return true
1299	}
1300	return false
1301}
1302
1303func (g *Generator) fileByName(filename string) *FileDescriptor {
1304	return g.allFilesByName[filename]
1305}
1306
1307// weak returns whether the ith import of the current file is a weak import.
1308func (g *Generator) weak(i int32) bool {
1309	for _, j := range g.file.WeakDependency {
1310		if j == i {
1311			return true
1312		}
1313	}
1314	return false
1315}
1316
1317// Generate the imports
1318func (g *Generator) generateImports() {
1319	// We almost always need a proto import.  Rather than computing when we
1320	// do, which is tricky when there's a plugin, just import it and
1321	// reference it later. The same argument applies to the fmt and math packages.
1322	g.P("import " + g.Pkg["proto"] + " " + strconv.Quote(g.ImportPrefix+"github.com/golang/protobuf/proto"))
1323	g.P("import " + g.Pkg["fmt"] + ` "fmt"`)
1324	g.P("import " + g.Pkg["math"] + ` "math"`)
1325	for i, s := range g.file.Dependency {
1326		fd := g.fileByName(s)
1327		// Do not import our own package.
1328		if fd.PackageName() == g.packageName {
1329			continue
1330		}
1331		filename := fd.goFileName()
1332		// By default, import path is the dirname of the Go filename.
1333		importPath := path.Dir(filename)
1334		if substitution, ok := g.ImportMap[s]; ok {
1335			importPath = substitution
1336		}
1337		importPath = g.ImportPrefix + importPath
1338		// Skip weak imports.
1339		if g.weak(int32(i)) {
1340			g.P("// skipping weak import ", fd.PackageName(), " ", strconv.Quote(importPath))
1341			continue
1342		}
1343		// We need to import all the dependencies, even if we don't reference them,
1344		// because other code and tools depend on having the full transitive closure
1345		// of protocol buffer types in the binary.
1346		pname := fd.PackageName()
1347		if _, ok := g.usedPackages[pname]; !ok {
1348			pname = "_"
1349		}
1350		g.P("import ", pname, " ", strconv.Quote(importPath))
1351	}
1352	g.P()
1353	// TODO: may need to worry about uniqueness across plugins
1354	for _, p := range plugins {
1355		p.GenerateImports(g.file)
1356		g.P()
1357	}
1358	g.P("// Reference imports to suppress errors if they are not otherwise used.")
1359	g.P("var _ = ", g.Pkg["proto"], ".Marshal")
1360	g.P("var _ = ", g.Pkg["fmt"], ".Errorf")
1361	g.P("var _ = ", g.Pkg["math"], ".Inf")
1362	g.P()
1363}
1364
1365func (g *Generator) generateImported(id *ImportedDescriptor) {
1366	// Don't generate public import symbols for files that we are generating
1367	// code for, since those symbols will already be in this package.
1368	// We can't simply avoid creating the ImportedDescriptor objects,
1369	// because g.genFiles isn't populated at that stage.
1370	tn := id.TypeName()
1371	sn := tn[len(tn)-1]
1372	df := g.FileOf(id.o.File())
1373	filename := *df.Name
1374	for _, fd := range g.genFiles {
1375		if *fd.Name == filename {
1376			g.P("// Ignoring public import of ", sn, " from ", filename)
1377			g.P()
1378			return
1379		}
1380	}
1381	g.P("// ", sn, " from public import ", filename)
1382	g.usedPackages[df.PackageName()] = true
1383
1384	for _, sym := range df.exported[id.o] {
1385		sym.GenerateAlias(g, df.PackageName())
1386	}
1387
1388	g.P()
1389}
1390
1391// Generate the enum definitions for this EnumDescriptor.
1392func (g *Generator) generateEnum(enum *EnumDescriptor) {
1393	// The full type name
1394	typeName := enum.TypeName()
1395	// The full type name, CamelCased.
1396	ccTypeName := CamelCaseSlice(typeName)
1397	ccPrefix := enum.prefix()
1398
1399	g.PrintComments(enum.path)
1400	g.P("type ", ccTypeName, " int32")
1401	g.file.addExport(enum, enumSymbol{ccTypeName, enum.proto3()})
1402	g.P("const (")
1403	g.In()
1404	for i, e := range enum.Value {
1405		g.PrintComments(fmt.Sprintf("%s,%d,%d", enum.path, enumValuePath, i))
1406
1407		name := ccPrefix + *e.Name
1408		g.P(name, " ", ccTypeName, " = ", e.Number)
1409		g.file.addExport(enum, constOrVarSymbol{name, "const", ccTypeName})
1410	}
1411	g.Out()
1412	g.P(")")
1413	g.P("var ", ccTypeName, "_name = map[int32]string{")
1414	g.In()
1415	generated := make(map[int32]bool) // avoid duplicate values
1416	for _, e := range enum.Value {
1417		duplicate := ""
1418		if _, present := generated[*e.Number]; present {
1419			duplicate = "// Duplicate value: "
1420		}
1421		g.P(duplicate, e.Number, ": ", strconv.Quote(*e.Name), ",")
1422		generated[*e.Number] = true
1423	}
1424	g.Out()
1425	g.P("}")
1426	g.P("var ", ccTypeName, "_value = map[string]int32{")
1427	g.In()
1428	for _, e := range enum.Value {
1429		g.P(strconv.Quote(*e.Name), ": ", e.Number, ",")
1430	}
1431	g.Out()
1432	g.P("}")
1433
1434	if !enum.proto3() {
1435		g.P("func (x ", ccTypeName, ") Enum() *", ccTypeName, " {")
1436		g.In()
1437		g.P("p := new(", ccTypeName, ")")
1438		g.P("*p = x")
1439		g.P("return p")
1440		g.Out()
1441		g.P("}")
1442	}
1443
1444	g.P("func (x ", ccTypeName, ") String() string {")
1445	g.In()
1446	g.P("return ", g.Pkg["proto"], ".EnumName(", ccTypeName, "_name, int32(x))")
1447	g.Out()
1448	g.P("}")
1449
1450	if !enum.proto3() {
1451		g.P("func (x *", ccTypeName, ") UnmarshalJSON(data []byte) error {")
1452		g.In()
1453		g.P("value, err := ", g.Pkg["proto"], ".UnmarshalJSONEnum(", ccTypeName, `_value, data, "`, ccTypeName, `")`)
1454		g.P("if err != nil {")
1455		g.In()
1456		g.P("return err")
1457		g.Out()
1458		g.P("}")
1459		g.P("*x = ", ccTypeName, "(value)")
1460		g.P("return nil")
1461		g.Out()
1462		g.P("}")
1463	}
1464
1465	var indexes []string
1466	for m := enum.parent; m != nil; m = m.parent {
1467		// XXX: skip groups?
1468		indexes = append([]string{strconv.Itoa(m.index)}, indexes...)
1469	}
1470	indexes = append(indexes, strconv.Itoa(enum.index))
1471	g.P("func (", ccTypeName, ") EnumDescriptor() ([]byte, []int) { return ", g.file.VarName(), ", []int{", strings.Join(indexes, ", "), "} }")
1472	if enum.file.GetPackage() == "google.protobuf" && enum.GetName() == "NullValue" {
1473		g.P("func (", ccTypeName, `) XXX_WellKnownType() string { return "`, enum.GetName(), `" }`)
1474	}
1475
1476	g.P()
1477}
1478
1479// The tag is a string like "varint,2,opt,name=fieldname,def=7" that
1480// identifies details of the field for the protocol buffer marshaling and unmarshaling
1481// code.  The fields are:
1482//	wire encoding
1483//	protocol tag number
1484//	opt,req,rep for optional, required, or repeated
1485//	packed whether the encoding is "packed" (optional; repeated primitives only)
1486//	name= the original declared name
1487//	enum= the name of the enum type if it is an enum-typed field.
1488//	proto3 if this field is in a proto3 message
1489//	def= string representation of the default value, if any.
1490// The default value must be in a representation that can be used at run-time
1491// to generate the default value. Thus bools become 0 and 1, for instance.
1492func (g *Generator) goTag(message *Descriptor, field *descriptor.FieldDescriptorProto, wiretype string) string {
1493	optrepreq := ""
1494	switch {
1495	case isOptional(field):
1496		optrepreq = "opt"
1497	case isRequired(field):
1498		optrepreq = "req"
1499	case isRepeated(field):
1500		optrepreq = "rep"
1501	}
1502	var defaultValue string
1503	if dv := field.DefaultValue; dv != nil { // set means an explicit default
1504		defaultValue = *dv
1505		// Some types need tweaking.
1506		switch *field.Type {
1507		case descriptor.FieldDescriptorProto_TYPE_BOOL:
1508			if defaultValue == "true" {
1509				defaultValue = "1"
1510			} else {
1511				defaultValue = "0"
1512			}
1513		case descriptor.FieldDescriptorProto_TYPE_STRING,
1514			descriptor.FieldDescriptorProto_TYPE_BYTES:
1515			// Nothing to do. Quoting is done for the whole tag.
1516		case descriptor.FieldDescriptorProto_TYPE_ENUM:
1517			// For enums we need to provide the integer constant.
1518			obj := g.ObjectNamed(field.GetTypeName())
1519			if id, ok := obj.(*ImportedDescriptor); ok {
1520				// It is an enum that was publicly imported.
1521				// We need the underlying type.
1522				obj = id.o
1523			}
1524			enum, ok := obj.(*EnumDescriptor)
1525			if !ok {
1526				log.Printf("obj is a %T", obj)
1527				if id, ok := obj.(*ImportedDescriptor); ok {
1528					log.Printf("id.o is a %T", id.o)
1529				}
1530				g.Fail("unknown enum type", CamelCaseSlice(obj.TypeName()))
1531			}
1532			defaultValue = enum.integerValueAsString(defaultValue)
1533		}
1534		defaultValue = ",def=" + defaultValue
1535	}
1536	enum := ""
1537	if *field.Type == descriptor.FieldDescriptorProto_TYPE_ENUM {
1538		// We avoid using obj.PackageName(), because we want to use the
1539		// original (proto-world) package name.
1540		obj := g.ObjectNamed(field.GetTypeName())
1541		if id, ok := obj.(*ImportedDescriptor); ok {
1542			obj = id.o
1543		}
1544		enum = ",enum="
1545		if pkg := obj.File().GetPackage(); pkg != "" {
1546			enum += pkg + "."
1547		}
1548		enum += CamelCaseSlice(obj.TypeName())
1549	}
1550	packed := ""
1551	if (field.Options != nil && field.Options.GetPacked()) ||
1552		// Per https://developers.google.com/protocol-buffers/docs/proto3#simple:
1553		// "In proto3, repeated fields of scalar numeric types use packed encoding by default."
1554		(message.proto3() && (field.Options == nil || field.Options.Packed == nil) &&
1555			isRepeated(field) && isScalar(field)) {
1556		packed = ",packed"
1557	}
1558	fieldName := field.GetName()
1559	name := fieldName
1560	if *field.Type == descriptor.FieldDescriptorProto_TYPE_GROUP {
1561		// We must use the type name for groups instead of
1562		// the field name to preserve capitalization.
1563		// type_name in FieldDescriptorProto is fully-qualified,
1564		// but we only want the local part.
1565		name = *field.TypeName
1566		if i := strings.LastIndex(name, "."); i >= 0 {
1567			name = name[i+1:]
1568		}
1569	}
1570	if json := field.GetJsonName(); json != "" && json != name {
1571		// TODO: escaping might be needed, in which case
1572		// perhaps this should be in its own "json" tag.
1573		name += ",json=" + json
1574	}
1575	name = ",name=" + name
1576	if message.proto3() {
1577		// We only need the extra tag for []byte fields;
1578		// no need to add noise for the others.
1579		if *field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES {
1580			name += ",proto3"
1581		}
1582
1583	}
1584	oneof := ""
1585	if field.OneofIndex != nil {
1586		oneof = ",oneof"
1587	}
1588	return strconv.Quote(fmt.Sprintf("%s,%d,%s%s%s%s%s%s",
1589		wiretype,
1590		field.GetNumber(),
1591		optrepreq,
1592		packed,
1593		name,
1594		enum,
1595		oneof,
1596		defaultValue))
1597}
1598
1599func needsStar(typ descriptor.FieldDescriptorProto_Type) bool {
1600	switch typ {
1601	case descriptor.FieldDescriptorProto_TYPE_GROUP:
1602		return false
1603	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
1604		return false
1605	case descriptor.FieldDescriptorProto_TYPE_BYTES:
1606		return false
1607	}
1608	return true
1609}
1610
1611// TypeName is the printed name appropriate for an item. If the object is in the current file,
1612// TypeName drops the package name and underscores the rest.
1613// Otherwise the object is from another package; and the result is the underscored
1614// package name followed by the item name.
1615// The result always has an initial capital.
1616func (g *Generator) TypeName(obj Object) string {
1617	return g.DefaultPackageName(obj) + CamelCaseSlice(obj.TypeName())
1618}
1619
1620// TypeNameWithPackage is like TypeName, but always includes the package
1621// name even if the object is in our own package.
1622func (g *Generator) TypeNameWithPackage(obj Object) string {
1623	return obj.PackageName() + CamelCaseSlice(obj.TypeName())
1624}
1625
1626// GoType returns a string representing the type name, and the wire type
1627func (g *Generator) GoType(message *Descriptor, field *descriptor.FieldDescriptorProto) (typ string, wire string) {
1628	// TODO: Options.
1629	switch *field.Type {
1630	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
1631		typ, wire = "float64", "fixed64"
1632	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
1633		typ, wire = "float32", "fixed32"
1634	case descriptor.FieldDescriptorProto_TYPE_INT64:
1635		typ, wire = "int64", "varint"
1636	case descriptor.FieldDescriptorProto_TYPE_UINT64:
1637		typ, wire = "uint64", "varint"
1638	case descriptor.FieldDescriptorProto_TYPE_INT32:
1639		typ, wire = "int32", "varint"
1640	case descriptor.FieldDescriptorProto_TYPE_UINT32:
1641		typ, wire = "uint32", "varint"
1642	case descriptor.FieldDescriptorProto_TYPE_FIXED64:
1643		typ, wire = "uint64", "fixed64"
1644	case descriptor.FieldDescriptorProto_TYPE_FIXED32:
1645		typ, wire = "uint32", "fixed32"
1646	case descriptor.FieldDescriptorProto_TYPE_BOOL:
1647		typ, wire = "bool", "varint"
1648	case descriptor.FieldDescriptorProto_TYPE_STRING:
1649		typ, wire = "string", "bytes"
1650	case descriptor.FieldDescriptorProto_TYPE_GROUP:
1651		desc := g.ObjectNamed(field.GetTypeName())
1652		typ, wire = "*"+g.TypeName(desc), "group"
1653	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
1654		desc := g.ObjectNamed(field.GetTypeName())
1655		typ, wire = "*"+g.TypeName(desc), "bytes"
1656	case descriptor.FieldDescriptorProto_TYPE_BYTES:
1657		typ, wire = "[]byte", "bytes"
1658	case descriptor.FieldDescriptorProto_TYPE_ENUM:
1659		desc := g.ObjectNamed(field.GetTypeName())
1660		typ, wire = g.TypeName(desc), "varint"
1661	case descriptor.FieldDescriptorProto_TYPE_SFIXED32:
1662		typ, wire = "int32", "fixed32"
1663	case descriptor.FieldDescriptorProto_TYPE_SFIXED64:
1664		typ, wire = "int64", "fixed64"
1665	case descriptor.FieldDescriptorProto_TYPE_SINT32:
1666		typ, wire = "int32", "zigzag32"
1667	case descriptor.FieldDescriptorProto_TYPE_SINT64:
1668		typ, wire = "int64", "zigzag64"
1669	default:
1670		g.Fail("unknown type for", field.GetName())
1671	}
1672	if isRepeated(field) {
1673		typ = "[]" + typ
1674	} else if message != nil && message.proto3() {
1675		return
1676	} else if field.OneofIndex != nil && message != nil {
1677		return
1678	} else if needsStar(*field.Type) {
1679		typ = "*" + typ
1680	}
1681	return
1682}
1683
1684func (g *Generator) RecordTypeUse(t string) {
1685	if obj, ok := g.typeNameToObject[t]; ok {
1686		// Call ObjectNamed to get the true object to record the use.
1687		obj = g.ObjectNamed(t)
1688		g.usedPackages[obj.PackageName()] = true
1689	}
1690}
1691
1692// Method names that may be generated.  Fields with these names get an
1693// underscore appended. Any change to this set is a potential incompatible
1694// API change because it changes generated field names.
1695var methodNames = [...]string{
1696	"Reset",
1697	"String",
1698	"ProtoMessage",
1699	"Marshal",
1700	"Unmarshal",
1701	"ExtensionRangeArray",
1702	"ExtensionMap",
1703	"Descriptor",
1704}
1705
1706// Names of messages in the `google.protobuf` package for which
1707// we will generate XXX_WellKnownType methods.
1708var wellKnownTypes = map[string]bool{
1709	"Any":       true,
1710	"Duration":  true,
1711	"Empty":     true,
1712	"Struct":    true,
1713	"Timestamp": true,
1714
1715	"Value":       true,
1716	"ListValue":   true,
1717	"DoubleValue": true,
1718	"FloatValue":  true,
1719	"Int64Value":  true,
1720	"UInt64Value": true,
1721	"Int32Value":  true,
1722	"UInt32Value": true,
1723	"BoolValue":   true,
1724	"StringValue": true,
1725	"BytesValue":  true,
1726}
1727
1728// Generate the type and default constant definitions for this Descriptor.
1729func (g *Generator) generateMessage(message *Descriptor) {
1730	// The full type name
1731	typeName := message.TypeName()
1732	// The full type name, CamelCased.
1733	ccTypeName := CamelCaseSlice(typeName)
1734
1735	usedNames := make(map[string]bool)
1736	for _, n := range methodNames {
1737		usedNames[n] = true
1738	}
1739	fieldNames := make(map[*descriptor.FieldDescriptorProto]string)
1740	fieldGetterNames := make(map[*descriptor.FieldDescriptorProto]string)
1741	fieldTypes := make(map[*descriptor.FieldDescriptorProto]string)
1742	mapFieldTypes := make(map[*descriptor.FieldDescriptorProto]string)
1743
1744	oneofFieldName := make(map[int32]string)                           // indexed by oneof_index field of FieldDescriptorProto
1745	oneofDisc := make(map[int32]string)                                // name of discriminator method
1746	oneofTypeName := make(map[*descriptor.FieldDescriptorProto]string) // without star
1747	oneofInsertPoints := make(map[int32]int)                           // oneof_index => offset of g.Buffer
1748
1749	g.PrintComments(message.path)
1750	g.P("type ", ccTypeName, " struct {")
1751	g.In()
1752
1753	// allocNames finds a conflict-free variation of the given strings,
1754	// consistently mutating their suffixes.
1755	// It returns the same number of strings.
1756	allocNames := func(ns ...string) []string {
1757	Loop:
1758		for {
1759			for _, n := range ns {
1760				if usedNames[n] {
1761					for i := range ns {
1762						ns[i] += "_"
1763					}
1764					continue Loop
1765				}
1766			}
1767			for _, n := range ns {
1768				usedNames[n] = true
1769			}
1770			return ns
1771		}
1772	}
1773
1774	for i, field := range message.Field {
1775		// Allocate the getter and the field at the same time so name
1776		// collisions create field/method consistent names.
1777		// TODO: This allocation occurs based on the order of the fields
1778		// in the proto file, meaning that a change in the field
1779		// ordering can change generated Method/Field names.
1780		base := CamelCase(*field.Name)
1781		ns := allocNames(base, "Get"+base)
1782		fieldName, fieldGetterName := ns[0], ns[1]
1783		typename, wiretype := g.GoType(message, field)
1784		jsonName := *field.Name
1785		tag := fmt.Sprintf("protobuf:%s json:%q", g.goTag(message, field, wiretype), jsonName+",omitempty")
1786
1787		fieldNames[field] = fieldName
1788		fieldGetterNames[field] = fieldGetterName
1789
1790		oneof := field.OneofIndex != nil
1791		if oneof && oneofFieldName[*field.OneofIndex] == "" {
1792			odp := message.OneofDecl[int(*field.OneofIndex)]
1793			fname := allocNames(CamelCase(odp.GetName()))[0]
1794
1795			// This is the first field of a oneof we haven't seen before.
1796			// Generate the union field.
1797			com := g.PrintComments(fmt.Sprintf("%s,%d,%d", message.path, messageOneofPath, *field.OneofIndex))
1798			if com {
1799				g.P("//")
1800			}
1801			g.P("// Types that are valid to be assigned to ", fname, ":")
1802			// Generate the rest of this comment later,
1803			// when we've computed any disambiguation.
1804			oneofInsertPoints[*field.OneofIndex] = g.Buffer.Len()
1805
1806			dname := "is" + ccTypeName + "_" + fname
1807			oneofFieldName[*field.OneofIndex] = fname
1808			oneofDisc[*field.OneofIndex] = dname
1809			tag := `protobuf_oneof:"` + odp.GetName() + `"`
1810			g.P(fname, " ", dname, " `", tag, "`")
1811		}
1812
1813		if *field.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE {
1814			desc := g.ObjectNamed(field.GetTypeName())
1815			if d, ok := desc.(*Descriptor); ok && d.GetOptions().GetMapEntry() {
1816				// Figure out the Go types and tags for the key and value types.
1817				keyField, valField := d.Field[0], d.Field[1]
1818				keyType, keyWire := g.GoType(d, keyField)
1819				valType, valWire := g.GoType(d, valField)
1820				keyTag, valTag := g.goTag(d, keyField, keyWire), g.goTag(d, valField, valWire)
1821
1822				// We don't use stars, except for message-typed values.
1823				// Message and enum types are the only two possibly foreign types used in maps,
1824				// so record their use. They are not permitted as map keys.
1825				keyType = strings.TrimPrefix(keyType, "*")
1826				switch *valField.Type {
1827				case descriptor.FieldDescriptorProto_TYPE_ENUM:
1828					valType = strings.TrimPrefix(valType, "*")
1829					g.RecordTypeUse(valField.GetTypeName())
1830				case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
1831					g.RecordTypeUse(valField.GetTypeName())
1832				default:
1833					valType = strings.TrimPrefix(valType, "*")
1834				}
1835
1836				typename = fmt.Sprintf("map[%s]%s", keyType, valType)
1837				mapFieldTypes[field] = typename // record for the getter generation
1838
1839				tag += fmt.Sprintf(" protobuf_key:%s protobuf_val:%s", keyTag, valTag)
1840			}
1841		}
1842
1843		fieldTypes[field] = typename
1844
1845		if oneof {
1846			tname := ccTypeName + "_" + fieldName
1847			// It is possible for this to collide with a message or enum
1848			// nested in this message. Check for collisions.
1849			for {
1850				ok := true
1851				for _, desc := range message.nested {
1852					if CamelCaseSlice(desc.TypeName()) == tname {
1853						ok = false
1854						break
1855					}
1856				}
1857				for _, enum := range message.enums {
1858					if CamelCaseSlice(enum.TypeName()) == tname {
1859						ok = false
1860						break
1861					}
1862				}
1863				if !ok {
1864					tname += "_"
1865					continue
1866				}
1867				break
1868			}
1869
1870			oneofTypeName[field] = tname
1871			continue
1872		}
1873
1874		g.PrintComments(fmt.Sprintf("%s,%d,%d", message.path, messageFieldPath, i))
1875		g.P(fieldName, "\t", typename, "\t`", tag, "`")
1876		g.RecordTypeUse(field.GetTypeName())
1877	}
1878	if len(message.ExtensionRange) > 0 {
1879		g.P(g.Pkg["proto"], ".XXX_InternalExtensions `json:\"-\"`")
1880	}
1881	if !message.proto3() {
1882		g.P("XXX_unrecognized\t[]byte `json:\"-\"`")
1883	}
1884	g.Out()
1885	g.P("}")
1886
1887	// Update g.Buffer to list valid oneof types.
1888	// We do this down here, after we've disambiguated the oneof type names.
1889	// We go in reverse order of insertion point to avoid invalidating offsets.
1890	for oi := int32(len(message.OneofDecl)); oi >= 0; oi-- {
1891		ip := oneofInsertPoints[oi]
1892		all := g.Buffer.Bytes()
1893		rem := all[ip:]
1894		g.Buffer = bytes.NewBuffer(all[:ip:ip]) // set cap so we don't scribble on rem
1895		for _, field := range message.Field {
1896			if field.OneofIndex == nil || *field.OneofIndex != oi {
1897				continue
1898			}
1899			g.P("//\t*", oneofTypeName[field])
1900		}
1901		g.Buffer.Write(rem)
1902	}
1903
1904	// Reset, String and ProtoMessage methods.
1905	g.P("func (m *", ccTypeName, ") Reset() { *m = ", ccTypeName, "{} }")
1906	g.P("func (m *", ccTypeName, ") String() string { return ", g.Pkg["proto"], ".CompactTextString(m) }")
1907	g.P("func (*", ccTypeName, ") ProtoMessage() {}")
1908	var indexes []string
1909	for m := message; m != nil; m = m.parent {
1910		indexes = append([]string{strconv.Itoa(m.index)}, indexes...)
1911	}
1912	g.P("func (*", ccTypeName, ") Descriptor() ([]byte, []int) { return ", g.file.VarName(), ", []int{", strings.Join(indexes, ", "), "} }")
1913	// TODO: Revisit the decision to use a XXX_WellKnownType method
1914	// if we change proto.MessageName to work with multiple equivalents.
1915	if message.file.GetPackage() == "google.protobuf" && wellKnownTypes[message.GetName()] {
1916		g.P("func (*", ccTypeName, `) XXX_WellKnownType() string { return "`, message.GetName(), `" }`)
1917	}
1918
1919	// Extension support methods
1920	var hasExtensions, isMessageSet bool
1921	if len(message.ExtensionRange) > 0 {
1922		hasExtensions = true
1923		// message_set_wire_format only makes sense when extensions are defined.
1924		if opts := message.Options; opts != nil && opts.GetMessageSetWireFormat() {
1925			isMessageSet = true
1926			g.P()
1927			g.P("func (m *", ccTypeName, ") Marshal() ([]byte, error) {")
1928			g.In()
1929			g.P("return ", g.Pkg["proto"], ".MarshalMessageSet(&m.XXX_InternalExtensions)")
1930			g.Out()
1931			g.P("}")
1932			g.P("func (m *", ccTypeName, ") Unmarshal(buf []byte) error {")
1933			g.In()
1934			g.P("return ", g.Pkg["proto"], ".UnmarshalMessageSet(buf, &m.XXX_InternalExtensions)")
1935			g.Out()
1936			g.P("}")
1937			g.P("func (m *", ccTypeName, ") MarshalJSON() ([]byte, error) {")
1938			g.In()
1939			g.P("return ", g.Pkg["proto"], ".MarshalMessageSetJSON(&m.XXX_InternalExtensions)")
1940			g.Out()
1941			g.P("}")
1942			g.P("func (m *", ccTypeName, ") UnmarshalJSON(buf []byte) error {")
1943			g.In()
1944			g.P("return ", g.Pkg["proto"], ".UnmarshalMessageSetJSON(buf, &m.XXX_InternalExtensions)")
1945			g.Out()
1946			g.P("}")
1947			g.P("// ensure ", ccTypeName, " satisfies proto.Marshaler and proto.Unmarshaler")
1948			g.P("var _ ", g.Pkg["proto"], ".Marshaler = (*", ccTypeName, ")(nil)")
1949			g.P("var _ ", g.Pkg["proto"], ".Unmarshaler = (*", ccTypeName, ")(nil)")
1950		}
1951
1952		g.P()
1953		g.P("var extRange_", ccTypeName, " = []", g.Pkg["proto"], ".ExtensionRange{")
1954		g.In()
1955		for _, r := range message.ExtensionRange {
1956			end := fmt.Sprint(*r.End - 1) // make range inclusive on both ends
1957			g.P("{", r.Start, ", ", end, "},")
1958		}
1959		g.Out()
1960		g.P("}")
1961		g.P("func (*", ccTypeName, ") ExtensionRangeArray() []", g.Pkg["proto"], ".ExtensionRange {")
1962		g.In()
1963		g.P("return extRange_", ccTypeName)
1964		g.Out()
1965		g.P("}")
1966	}
1967
1968	// Default constants
1969	defNames := make(map[*descriptor.FieldDescriptorProto]string)
1970	for _, field := range message.Field {
1971		def := field.GetDefaultValue()
1972		if def == "" {
1973			continue
1974		}
1975		fieldname := "Default_" + ccTypeName + "_" + CamelCase(*field.Name)
1976		defNames[field] = fieldname
1977		typename, _ := g.GoType(message, field)
1978		if typename[0] == '*' {
1979			typename = typename[1:]
1980		}
1981		kind := "const "
1982		switch {
1983		case typename == "bool":
1984		case typename == "string":
1985			def = strconv.Quote(def)
1986		case typename == "[]byte":
1987			def = "[]byte(" + strconv.Quote(def) + ")"
1988			kind = "var "
1989		case def == "inf", def == "-inf", def == "nan":
1990			// These names are known to, and defined by, the protocol language.
1991			switch def {
1992			case "inf":
1993				def = "math.Inf(1)"
1994			case "-inf":
1995				def = "math.Inf(-1)"
1996			case "nan":
1997				def = "math.NaN()"
1998			}
1999			if *field.Type == descriptor.FieldDescriptorProto_TYPE_FLOAT {
2000				def = "float32(" + def + ")"
2001			}
2002			kind = "var "
2003		case *field.Type == descriptor.FieldDescriptorProto_TYPE_ENUM:
2004			// Must be an enum.  Need to construct the prefixed name.
2005			obj := g.ObjectNamed(field.GetTypeName())
2006			var enum *EnumDescriptor
2007			if id, ok := obj.(*ImportedDescriptor); ok {
2008				// The enum type has been publicly imported.
2009				enum, _ = id.o.(*EnumDescriptor)
2010			} else {
2011				enum, _ = obj.(*EnumDescriptor)
2012			}
2013			if enum == nil {
2014				log.Printf("don't know how to generate constant for %s", fieldname)
2015				continue
2016			}
2017			def = g.DefaultPackageName(obj) + enum.prefix() + def
2018		}
2019		g.P(kind, fieldname, " ", typename, " = ", def)
2020		g.file.addExport(message, constOrVarSymbol{fieldname, kind, ""})
2021	}
2022	g.P()
2023
2024	// Oneof per-field types, discriminants and getters.
2025	//
2026	// Generate unexported named types for the discriminant interfaces.
2027	// We shouldn't have to do this, but there was (~19 Aug 2015) a compiler/linker bug
2028	// that was triggered by using anonymous interfaces here.
2029	// TODO: Revisit this and consider reverting back to anonymous interfaces.
2030	for oi := range message.OneofDecl {
2031		dname := oneofDisc[int32(oi)]
2032		g.P("type ", dname, " interface { ", dname, "() }")
2033	}
2034	g.P()
2035	for _, field := range message.Field {
2036		if field.OneofIndex == nil {
2037			continue
2038		}
2039		_, wiretype := g.GoType(message, field)
2040		tag := "protobuf:" + g.goTag(message, field, wiretype)
2041		g.P("type ", oneofTypeName[field], " struct{ ", fieldNames[field], " ", fieldTypes[field], " `", tag, "` }")
2042		g.RecordTypeUse(field.GetTypeName())
2043	}
2044	g.P()
2045	for _, field := range message.Field {
2046		if field.OneofIndex == nil {
2047			continue
2048		}
2049		g.P("func (*", oneofTypeName[field], ") ", oneofDisc[*field.OneofIndex], "() {}")
2050	}
2051	g.P()
2052	for oi := range message.OneofDecl {
2053		fname := oneofFieldName[int32(oi)]
2054		g.P("func (m *", ccTypeName, ") Get", fname, "() ", oneofDisc[int32(oi)], " {")
2055		g.P("if m != nil { return m.", fname, " }")
2056		g.P("return nil")
2057		g.P("}")
2058	}
2059	g.P()
2060
2061	// Field getters
2062	var getters []getterSymbol
2063	for _, field := range message.Field {
2064		oneof := field.OneofIndex != nil
2065
2066		fname := fieldNames[field]
2067		typename, _ := g.GoType(message, field)
2068		if t, ok := mapFieldTypes[field]; ok {
2069			typename = t
2070		}
2071		mname := fieldGetterNames[field]
2072		star := ""
2073		if needsStar(*field.Type) && typename[0] == '*' {
2074			typename = typename[1:]
2075			star = "*"
2076		}
2077
2078		// Only export getter symbols for basic types,
2079		// and for messages and enums in the same package.
2080		// Groups are not exported.
2081		// Foreign types can't be hoisted through a public import because
2082		// the importer may not already be importing the defining .proto.
2083		// As an example, imagine we have an import tree like this:
2084		//   A.proto -> B.proto -> C.proto
2085		// If A publicly imports B, we need to generate the getters from B in A's output,
2086		// but if one such getter returns something from C then we cannot do that
2087		// because A is not importing C already.
2088		var getter, genType bool
2089		switch *field.Type {
2090		case descriptor.FieldDescriptorProto_TYPE_GROUP:
2091			getter = false
2092		case descriptor.FieldDescriptorProto_TYPE_MESSAGE, descriptor.FieldDescriptorProto_TYPE_ENUM:
2093			// Only export getter if its return type is in this package.
2094			getter = g.ObjectNamed(field.GetTypeName()).PackageName() == message.PackageName()
2095			genType = true
2096		default:
2097			getter = true
2098		}
2099		if getter {
2100			getters = append(getters, getterSymbol{
2101				name:     mname,
2102				typ:      typename,
2103				typeName: field.GetTypeName(),
2104				genType:  genType,
2105			})
2106		}
2107
2108		g.P("func (m *", ccTypeName, ") "+mname+"() "+typename+" {")
2109		g.In()
2110		def, hasDef := defNames[field]
2111		typeDefaultIsNil := false // whether this field type's default value is a literal nil unless specified
2112		switch *field.Type {
2113		case descriptor.FieldDescriptorProto_TYPE_BYTES:
2114			typeDefaultIsNil = !hasDef
2115		case descriptor.FieldDescriptorProto_TYPE_GROUP, descriptor.FieldDescriptorProto_TYPE_MESSAGE:
2116			typeDefaultIsNil = true
2117		}
2118		if isRepeated(field) {
2119			typeDefaultIsNil = true
2120		}
2121		if typeDefaultIsNil && !oneof {
2122			// A bytes field with no explicit default needs less generated code,
2123			// as does a message or group field, or a repeated field.
2124			g.P("if m != nil {")
2125			g.In()
2126			g.P("return m." + fname)
2127			g.Out()
2128			g.P("}")
2129			g.P("return nil")
2130			g.Out()
2131			g.P("}")
2132			g.P()
2133			continue
2134		}
2135		if !oneof {
2136			if message.proto3() {
2137				g.P("if m != nil {")
2138			} else {
2139				g.P("if m != nil && m." + fname + " != nil {")
2140			}
2141			g.In()
2142			g.P("return " + star + "m." + fname)
2143			g.Out()
2144			g.P("}")
2145		} else {
2146			uname := oneofFieldName[*field.OneofIndex]
2147			tname := oneofTypeName[field]
2148			g.P("if x, ok := m.Get", uname, "().(*", tname, "); ok {")
2149			g.P("return x.", fname)
2150			g.P("}")
2151		}
2152		if hasDef {
2153			if *field.Type != descriptor.FieldDescriptorProto_TYPE_BYTES {
2154				g.P("return " + def)
2155			} else {
2156				// The default is a []byte var.
2157				// Make a copy when returning it to be safe.
2158				g.P("return append([]byte(nil), ", def, "...)")
2159			}
2160		} else {
2161			switch *field.Type {
2162			case descriptor.FieldDescriptorProto_TYPE_BOOL:
2163				g.P("return false")
2164			case descriptor.FieldDescriptorProto_TYPE_STRING:
2165				g.P(`return ""`)
2166			case descriptor.FieldDescriptorProto_TYPE_GROUP,
2167				descriptor.FieldDescriptorProto_TYPE_MESSAGE,
2168				descriptor.FieldDescriptorProto_TYPE_BYTES:
2169				// This is only possible for oneof fields.
2170				g.P("return nil")
2171			case descriptor.FieldDescriptorProto_TYPE_ENUM:
2172				// The default default for an enum is the first value in the enum,
2173				// not zero.
2174				obj := g.ObjectNamed(field.GetTypeName())
2175				var enum *EnumDescriptor
2176				if id, ok := obj.(*ImportedDescriptor); ok {
2177					// The enum type has been publicly imported.
2178					enum, _ = id.o.(*EnumDescriptor)
2179				} else {
2180					enum, _ = obj.(*EnumDescriptor)
2181				}
2182				if enum == nil {
2183					log.Printf("don't know how to generate getter for %s", field.GetName())
2184					continue
2185				}
2186				if len(enum.Value) == 0 {
2187					g.P("return 0 // empty enum")
2188				} else {
2189					first := enum.Value[0].GetName()
2190					g.P("return ", g.DefaultPackageName(obj)+enum.prefix()+first)
2191				}
2192			default:
2193				g.P("return 0")
2194			}
2195		}
2196		g.Out()
2197		g.P("}")
2198		g.P()
2199	}
2200
2201	if !message.group {
2202		ms := &messageSymbol{
2203			sym:           ccTypeName,
2204			hasExtensions: hasExtensions,
2205			isMessageSet:  isMessageSet,
2206			hasOneof:      len(message.OneofDecl) > 0,
2207			getters:       getters,
2208		}
2209		g.file.addExport(message, ms)
2210	}
2211
2212	// Oneof functions
2213	if len(message.OneofDecl) > 0 {
2214		fieldWire := make(map[*descriptor.FieldDescriptorProto]string)
2215
2216		// method
2217		enc := "_" + ccTypeName + "_OneofMarshaler"
2218		dec := "_" + ccTypeName + "_OneofUnmarshaler"
2219		size := "_" + ccTypeName + "_OneofSizer"
2220		encSig := "(msg " + g.Pkg["proto"] + ".Message, b *" + g.Pkg["proto"] + ".Buffer) error"
2221		decSig := "(msg " + g.Pkg["proto"] + ".Message, tag, wire int, b *" + g.Pkg["proto"] + ".Buffer) (bool, error)"
2222		sizeSig := "(msg " + g.Pkg["proto"] + ".Message) (n int)"
2223
2224		g.P("// XXX_OneofFuncs is for the internal use of the proto package.")
2225		g.P("func (*", ccTypeName, ") XXX_OneofFuncs() (func", encSig, ", func", decSig, ", func", sizeSig, ", []interface{}) {")
2226		g.P("return ", enc, ", ", dec, ", ", size, ", []interface{}{")
2227		for _, field := range message.Field {
2228			if field.OneofIndex == nil {
2229				continue
2230			}
2231			g.P("(*", oneofTypeName[field], ")(nil),")
2232		}
2233		g.P("}")
2234		g.P("}")
2235		g.P()
2236
2237		// marshaler
2238		g.P("func ", enc, encSig, " {")
2239		g.P("m := msg.(*", ccTypeName, ")")
2240		for oi, odp := range message.OneofDecl {
2241			g.P("// ", odp.GetName())
2242			fname := oneofFieldName[int32(oi)]
2243			g.P("switch x := m.", fname, ".(type) {")
2244			for _, field := range message.Field {
2245				if field.OneofIndex == nil || int(*field.OneofIndex) != oi {
2246					continue
2247				}
2248				g.P("case *", oneofTypeName[field], ":")
2249				var wire, pre, post string
2250				val := "x." + fieldNames[field] // overridden for TYPE_BOOL
2251				canFail := false                // only TYPE_MESSAGE and TYPE_GROUP can fail
2252				switch *field.Type {
2253				case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
2254					wire = "WireFixed64"
2255					pre = "b.EncodeFixed64(" + g.Pkg["math"] + ".Float64bits("
2256					post = "))"
2257				case descriptor.FieldDescriptorProto_TYPE_FLOAT:
2258					wire = "WireFixed32"
2259					pre = "b.EncodeFixed32(uint64(" + g.Pkg["math"] + ".Float32bits("
2260					post = ")))"
2261				case descriptor.FieldDescriptorProto_TYPE_INT64,
2262					descriptor.FieldDescriptorProto_TYPE_UINT64:
2263					wire = "WireVarint"
2264					pre, post = "b.EncodeVarint(uint64(", "))"
2265				case descriptor.FieldDescriptorProto_TYPE_INT32,
2266					descriptor.FieldDescriptorProto_TYPE_UINT32,
2267					descriptor.FieldDescriptorProto_TYPE_ENUM:
2268					wire = "WireVarint"
2269					pre, post = "b.EncodeVarint(uint64(", "))"
2270				case descriptor.FieldDescriptorProto_TYPE_FIXED64,
2271					descriptor.FieldDescriptorProto_TYPE_SFIXED64:
2272					wire = "WireFixed64"
2273					pre, post = "b.EncodeFixed64(uint64(", "))"
2274				case descriptor.FieldDescriptorProto_TYPE_FIXED32,
2275					descriptor.FieldDescriptorProto_TYPE_SFIXED32:
2276					wire = "WireFixed32"
2277					pre, post = "b.EncodeFixed32(uint64(", "))"
2278				case descriptor.FieldDescriptorProto_TYPE_BOOL:
2279					// bool needs special handling.
2280					g.P("t := uint64(0)")
2281					g.P("if ", val, " { t = 1 }")
2282					val = "t"
2283					wire = "WireVarint"
2284					pre, post = "b.EncodeVarint(", ")"
2285				case descriptor.FieldDescriptorProto_TYPE_STRING:
2286					wire = "WireBytes"
2287					pre, post = "b.EncodeStringBytes(", ")"
2288				case descriptor.FieldDescriptorProto_TYPE_GROUP:
2289					wire = "WireStartGroup"
2290					pre, post = "b.Marshal(", ")"
2291					canFail = true
2292				case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
2293					wire = "WireBytes"
2294					pre, post = "b.EncodeMessage(", ")"
2295					canFail = true
2296				case descriptor.FieldDescriptorProto_TYPE_BYTES:
2297					wire = "WireBytes"
2298					pre, post = "b.EncodeRawBytes(", ")"
2299				case descriptor.FieldDescriptorProto_TYPE_SINT32:
2300					wire = "WireVarint"
2301					pre, post = "b.EncodeZigzag32(uint64(", "))"
2302				case descriptor.FieldDescriptorProto_TYPE_SINT64:
2303					wire = "WireVarint"
2304					pre, post = "b.EncodeZigzag64(uint64(", "))"
2305				default:
2306					g.Fail("unhandled oneof field type ", field.Type.String())
2307				}
2308				fieldWire[field] = wire
2309				g.P("b.EncodeVarint(", field.Number, "<<3|", g.Pkg["proto"], ".", wire, ")")
2310				if !canFail {
2311					g.P(pre, val, post)
2312				} else {
2313					g.P("if err := ", pre, val, post, "; err != nil {")
2314					g.P("return err")
2315					g.P("}")
2316				}
2317				if *field.Type == descriptor.FieldDescriptorProto_TYPE_GROUP {
2318					g.P("b.EncodeVarint(", field.Number, "<<3|", g.Pkg["proto"], ".WireEndGroup)")
2319				}
2320			}
2321			g.P("case nil:")
2322			g.P("default: return ", g.Pkg["fmt"], `.Errorf("`, ccTypeName, ".", fname, ` has unexpected type %T", x)`)
2323			g.P("}")
2324		}
2325		g.P("return nil")
2326		g.P("}")
2327		g.P()
2328
2329		// unmarshaler
2330		g.P("func ", dec, decSig, " {")
2331		g.P("m := msg.(*", ccTypeName, ")")
2332		g.P("switch tag {")
2333		for _, field := range message.Field {
2334			if field.OneofIndex == nil {
2335				continue
2336			}
2337			odp := message.OneofDecl[int(*field.OneofIndex)]
2338			g.P("case ", field.Number, ": // ", odp.GetName(), ".", *field.Name)
2339			g.P("if wire != ", g.Pkg["proto"], ".", fieldWire[field], " {")
2340			g.P("return true, ", g.Pkg["proto"], ".ErrInternalBadWireType")
2341			g.P("}")
2342			lhs := "x, err" // overridden for TYPE_MESSAGE and TYPE_GROUP
2343			var dec, cast, cast2 string
2344			switch *field.Type {
2345			case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
2346				dec, cast = "b.DecodeFixed64()", g.Pkg["math"]+".Float64frombits"
2347			case descriptor.FieldDescriptorProto_TYPE_FLOAT:
2348				dec, cast, cast2 = "b.DecodeFixed32()", "uint32", g.Pkg["math"]+".Float32frombits"
2349			case descriptor.FieldDescriptorProto_TYPE_INT64:
2350				dec, cast = "b.DecodeVarint()", "int64"
2351			case descriptor.FieldDescriptorProto_TYPE_UINT64:
2352				dec = "b.DecodeVarint()"
2353			case descriptor.FieldDescriptorProto_TYPE_INT32:
2354				dec, cast = "b.DecodeVarint()", "int32"
2355			case descriptor.FieldDescriptorProto_TYPE_FIXED64:
2356				dec = "b.DecodeFixed64()"
2357			case descriptor.FieldDescriptorProto_TYPE_FIXED32:
2358				dec, cast = "b.DecodeFixed32()", "uint32"
2359			case descriptor.FieldDescriptorProto_TYPE_BOOL:
2360				dec = "b.DecodeVarint()"
2361				// handled specially below
2362			case descriptor.FieldDescriptorProto_TYPE_STRING:
2363				dec = "b.DecodeStringBytes()"
2364			case descriptor.FieldDescriptorProto_TYPE_GROUP:
2365				g.P("msg := new(", fieldTypes[field][1:], ")") // drop star
2366				lhs = "err"
2367				dec = "b.DecodeGroup(msg)"
2368				// handled specially below
2369			case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
2370				g.P("msg := new(", fieldTypes[field][1:], ")") // drop star
2371				lhs = "err"
2372				dec = "b.DecodeMessage(msg)"
2373				// handled specially below
2374			case descriptor.FieldDescriptorProto_TYPE_BYTES:
2375				dec = "b.DecodeRawBytes(true)"
2376			case descriptor.FieldDescriptorProto_TYPE_UINT32:
2377				dec, cast = "b.DecodeVarint()", "uint32"
2378			case descriptor.FieldDescriptorProto_TYPE_ENUM:
2379				dec, cast = "b.DecodeVarint()", fieldTypes[field]
2380			case descriptor.FieldDescriptorProto_TYPE_SFIXED32:
2381				dec, cast = "b.DecodeFixed32()", "int32"
2382			case descriptor.FieldDescriptorProto_TYPE_SFIXED64:
2383				dec, cast = "b.DecodeFixed64()", "int64"
2384			case descriptor.FieldDescriptorProto_TYPE_SINT32:
2385				dec, cast = "b.DecodeZigzag32()", "int32"
2386			case descriptor.FieldDescriptorProto_TYPE_SINT64:
2387				dec, cast = "b.DecodeZigzag64()", "int64"
2388			default:
2389				g.Fail("unhandled oneof field type ", field.Type.String())
2390			}
2391			g.P(lhs, " := ", dec)
2392			val := "x"
2393			if cast != "" {
2394				val = cast + "(" + val + ")"
2395			}
2396			if cast2 != "" {
2397				val = cast2 + "(" + val + ")"
2398			}
2399			switch *field.Type {
2400			case descriptor.FieldDescriptorProto_TYPE_BOOL:
2401				val += " != 0"
2402			case descriptor.FieldDescriptorProto_TYPE_GROUP,
2403				descriptor.FieldDescriptorProto_TYPE_MESSAGE:
2404				val = "msg"
2405			}
2406			g.P("m.", oneofFieldName[*field.OneofIndex], " = &", oneofTypeName[field], "{", val, "}")
2407			g.P("return true, err")
2408		}
2409		g.P("default: return false, nil")
2410		g.P("}")
2411		g.P("}")
2412		g.P()
2413
2414		// sizer
2415		g.P("func ", size, sizeSig, " {")
2416		g.P("m := msg.(*", ccTypeName, ")")
2417		for oi, odp := range message.OneofDecl {
2418			g.P("// ", odp.GetName())
2419			fname := oneofFieldName[int32(oi)]
2420			g.P("switch x := m.", fname, ".(type) {")
2421			for _, field := range message.Field {
2422				if field.OneofIndex == nil || int(*field.OneofIndex) != oi {
2423					continue
2424				}
2425				g.P("case *", oneofTypeName[field], ":")
2426				val := "x." + fieldNames[field]
2427				var wire, varint, fixed string
2428				switch *field.Type {
2429				case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
2430					wire = "WireFixed64"
2431					fixed = "8"
2432				case descriptor.FieldDescriptorProto_TYPE_FLOAT:
2433					wire = "WireFixed32"
2434					fixed = "4"
2435				case descriptor.FieldDescriptorProto_TYPE_INT64,
2436					descriptor.FieldDescriptorProto_TYPE_UINT64,
2437					descriptor.FieldDescriptorProto_TYPE_INT32,
2438					descriptor.FieldDescriptorProto_TYPE_UINT32,
2439					descriptor.FieldDescriptorProto_TYPE_ENUM:
2440					wire = "WireVarint"
2441					varint = val
2442				case descriptor.FieldDescriptorProto_TYPE_FIXED64,
2443					descriptor.FieldDescriptorProto_TYPE_SFIXED64:
2444					wire = "WireFixed64"
2445					fixed = "8"
2446				case descriptor.FieldDescriptorProto_TYPE_FIXED32,
2447					descriptor.FieldDescriptorProto_TYPE_SFIXED32:
2448					wire = "WireFixed32"
2449					fixed = "4"
2450				case descriptor.FieldDescriptorProto_TYPE_BOOL:
2451					wire = "WireVarint"
2452					fixed = "1"
2453				case descriptor.FieldDescriptorProto_TYPE_STRING:
2454					wire = "WireBytes"
2455					fixed = "len(" + val + ")"
2456					varint = fixed
2457				case descriptor.FieldDescriptorProto_TYPE_GROUP:
2458					wire = "WireStartGroup"
2459					fixed = g.Pkg["proto"] + ".Size(" + val + ")"
2460				case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
2461					wire = "WireBytes"
2462					g.P("s := ", g.Pkg["proto"], ".Size(", val, ")")
2463					fixed = "s"
2464					varint = fixed
2465				case descriptor.FieldDescriptorProto_TYPE_BYTES:
2466					wire = "WireBytes"
2467					fixed = "len(" + val + ")"
2468					varint = fixed
2469				case descriptor.FieldDescriptorProto_TYPE_SINT32:
2470					wire = "WireVarint"
2471					varint = "(uint32(" + val + ") << 1) ^ uint32((int32(" + val + ") >> 31))"
2472				case descriptor.FieldDescriptorProto_TYPE_SINT64:
2473					wire = "WireVarint"
2474					varint = "uint64(" + val + " << 1) ^ uint64((int64(" + val + ") >> 63))"
2475				default:
2476					g.Fail("unhandled oneof field type ", field.Type.String())
2477				}
2478				g.P("n += ", g.Pkg["proto"], ".SizeVarint(", field.Number, "<<3|", g.Pkg["proto"], ".", wire, ")")
2479				if varint != "" {
2480					g.P("n += ", g.Pkg["proto"], ".SizeVarint(uint64(", varint, "))")
2481				}
2482				if fixed != "" {
2483					g.P("n += ", fixed)
2484				}
2485				if *field.Type == descriptor.FieldDescriptorProto_TYPE_GROUP {
2486					g.P("n += ", g.Pkg["proto"], ".SizeVarint(", field.Number, "<<3|", g.Pkg["proto"], ".WireEndGroup)")
2487				}
2488			}
2489			g.P("case nil:")
2490			g.P("default:")
2491			g.P("panic(", g.Pkg["fmt"], ".Sprintf(\"proto: unexpected type %T in oneof\", x))")
2492			g.P("}")
2493		}
2494		g.P("return n")
2495		g.P("}")
2496		g.P()
2497	}
2498
2499	for _, ext := range message.ext {
2500		g.generateExtension(ext)
2501	}
2502
2503	fullName := strings.Join(message.TypeName(), ".")
2504	if g.file.Package != nil {
2505		fullName = *g.file.Package + "." + fullName
2506	}
2507
2508	g.addInitf("%s.RegisterType((*%s)(nil), %q)", g.Pkg["proto"], ccTypeName, fullName)
2509}
2510
2511func (g *Generator) generateExtension(ext *ExtensionDescriptor) {
2512	ccTypeName := ext.DescName()
2513
2514	extObj := g.ObjectNamed(*ext.Extendee)
2515	var extDesc *Descriptor
2516	if id, ok := extObj.(*ImportedDescriptor); ok {
2517		// This is extending a publicly imported message.
2518		// We need the underlying type for goTag.
2519		extDesc = id.o.(*Descriptor)
2520	} else {
2521		extDesc = extObj.(*Descriptor)
2522	}
2523	extendedType := "*" + g.TypeName(extObj) // always use the original
2524	field := ext.FieldDescriptorProto
2525	fieldType, wireType := g.GoType(ext.parent, field)
2526	tag := g.goTag(extDesc, field, wireType)
2527	g.RecordTypeUse(*ext.Extendee)
2528	if n := ext.FieldDescriptorProto.TypeName; n != nil {
2529		// foreign extension type
2530		g.RecordTypeUse(*n)
2531	}
2532
2533	typeName := ext.TypeName()
2534
2535	// Special case for proto2 message sets: If this extension is extending
2536	// proto2_bridge.MessageSet, and its final name component is "message_set_extension",
2537	// then drop that last component.
2538	mset := false
2539	if extendedType == "*proto2_bridge.MessageSet" && typeName[len(typeName)-1] == "message_set_extension" {
2540		typeName = typeName[:len(typeName)-1]
2541		mset = true
2542	}
2543
2544	// For text formatting, the package must be exactly what the .proto file declares,
2545	// ignoring overrides such as the go_package option, and with no dot/underscore mapping.
2546	extName := strings.Join(typeName, ".")
2547	if g.file.Package != nil {
2548		extName = *g.file.Package + "." + extName
2549	}
2550
2551	g.P("var ", ccTypeName, " = &", g.Pkg["proto"], ".ExtensionDesc{")
2552	g.In()
2553	g.P("ExtendedType: (", extendedType, ")(nil),")
2554	g.P("ExtensionType: (", fieldType, ")(nil),")
2555	g.P("Field: ", field.Number, ",")
2556	g.P(`Name: "`, extName, `",`)
2557	g.P("Tag: ", tag, ",")
2558	g.P(`Filename: "`, g.file.GetName(), `",`)
2559
2560	g.Out()
2561	g.P("}")
2562	g.P()
2563
2564	if mset {
2565		// Generate a bit more code to register with message_set.go.
2566		g.addInitf("%s.RegisterMessageSetType((%s)(nil), %d, %q)", g.Pkg["proto"], fieldType, *field.Number, extName)
2567	}
2568
2569	g.file.addExport(ext, constOrVarSymbol{ccTypeName, "var", ""})
2570}
2571
2572func (g *Generator) generateInitFunction() {
2573	for _, enum := range g.file.enum {
2574		g.generateEnumRegistration(enum)
2575	}
2576	for _, d := range g.file.desc {
2577		for _, ext := range d.ext {
2578			g.generateExtensionRegistration(ext)
2579		}
2580	}
2581	for _, ext := range g.file.ext {
2582		g.generateExtensionRegistration(ext)
2583	}
2584	if len(g.init) == 0 {
2585		return
2586	}
2587	g.P("func init() {")
2588	g.In()
2589	for _, l := range g.init {
2590		g.P(l)
2591	}
2592	g.Out()
2593	g.P("}")
2594	g.init = nil
2595}
2596
2597func (g *Generator) generateFileDescriptor(file *FileDescriptor) {
2598	// Make a copy and trim source_code_info data.
2599	// TODO: Trim this more when we know exactly what we need.
2600	pb := proto.Clone(file.FileDescriptorProto).(*descriptor.FileDescriptorProto)
2601	pb.SourceCodeInfo = nil
2602
2603	b, err := proto.Marshal(pb)
2604	if err != nil {
2605		g.Fail(err.Error())
2606	}
2607
2608	var buf bytes.Buffer
2609	w, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression)
2610	w.Write(b)
2611	w.Close()
2612	b = buf.Bytes()
2613
2614	v := file.VarName()
2615	g.P()
2616	g.P("func init() { ", g.Pkg["proto"], ".RegisterFile(", strconv.Quote(*file.Name), ", ", v, ") }")
2617	g.P("var ", v, " = []byte{")
2618	g.In()
2619	g.P("// ", len(b), " bytes of a gzipped FileDescriptorProto")
2620	for len(b) > 0 {
2621		n := 16
2622		if n > len(b) {
2623			n = len(b)
2624		}
2625
2626		s := ""
2627		for _, c := range b[:n] {
2628			s += fmt.Sprintf("0x%02x,", c)
2629		}
2630		g.P(s)
2631
2632		b = b[n:]
2633	}
2634	g.Out()
2635	g.P("}")
2636}
2637
2638func (g *Generator) generateEnumRegistration(enum *EnumDescriptor) {
2639	// // We always print the full (proto-world) package name here.
2640	pkg := enum.File().GetPackage()
2641	if pkg != "" {
2642		pkg += "."
2643	}
2644	// The full type name
2645	typeName := enum.TypeName()
2646	// The full type name, CamelCased.
2647	ccTypeName := CamelCaseSlice(typeName)
2648	g.addInitf("%s.RegisterEnum(%q, %[3]s_name, %[3]s_value)", g.Pkg["proto"], pkg+ccTypeName, ccTypeName)
2649}
2650
2651func (g *Generator) generateExtensionRegistration(ext *ExtensionDescriptor) {
2652	g.addInitf("%s.RegisterExtension(%s)", g.Pkg["proto"], ext.DescName())
2653}
2654
2655// And now lots of helper functions.
2656
2657// Is c an ASCII lower-case letter?
2658func isASCIILower(c byte) bool {
2659	return 'a' <= c && c <= 'z'
2660}
2661
2662// Is c an ASCII digit?
2663func isASCIIDigit(c byte) bool {
2664	return '0' <= c && c <= '9'
2665}
2666
2667// CamelCase returns the CamelCased name.
2668// If there is an interior underscore followed by a lower case letter,
2669// drop the underscore and convert the letter to upper case.
2670// There is a remote possibility of this rewrite causing a name collision,
2671// but it's so remote we're prepared to pretend it's nonexistent - since the
2672// C++ generator lowercases names, it's extremely unlikely to have two fields
2673// with different capitalizations.
2674// In short, _my_field_name_2 becomes XMyFieldName_2.
2675func CamelCase(s string) string {
2676	if s == "" {
2677		return ""
2678	}
2679	t := make([]byte, 0, 32)
2680	i := 0
2681	if s[0] == '_' {
2682		// Need a capital letter; drop the '_'.
2683		t = append(t, 'X')
2684		i++
2685	}
2686	// Invariant: if the next letter is lower case, it must be converted
2687	// to upper case.
2688	// That is, we process a word at a time, where words are marked by _ or
2689	// upper case letter. Digits are treated as words.
2690	for ; i < len(s); i++ {
2691		c := s[i]
2692		if c == '_' && i+1 < len(s) && isASCIILower(s[i+1]) {
2693			continue // Skip the underscore in s.
2694		}
2695		if isASCIIDigit(c) {
2696			t = append(t, c)
2697			continue
2698		}
2699		// Assume we have a letter now - if not, it's a bogus identifier.
2700		// The next word is a sequence of characters that must start upper case.
2701		if isASCIILower(c) {
2702			c ^= ' ' // Make it a capital letter.
2703		}
2704		t = append(t, c) // Guaranteed not lower case.
2705		// Accept lower case sequence that follows.
2706		for i+1 < len(s) && isASCIILower(s[i+1]) {
2707			i++
2708			t = append(t, s[i])
2709		}
2710	}
2711	return string(t)
2712}
2713
2714// CamelCaseSlice is like CamelCase, but the argument is a slice of strings to
2715// be joined with "_".
2716func CamelCaseSlice(elem []string) string { return CamelCase(strings.Join(elem, "_")) }
2717
2718// dottedSlice turns a sliced name into a dotted name.
2719func dottedSlice(elem []string) string { return strings.Join(elem, ".") }
2720
2721// Is this field optional?
2722func isOptional(field *descriptor.FieldDescriptorProto) bool {
2723	return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_OPTIONAL
2724}
2725
2726// Is this field required?
2727func isRequired(field *descriptor.FieldDescriptorProto) bool {
2728	return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REQUIRED
2729}
2730
2731// Is this field repeated?
2732func isRepeated(field *descriptor.FieldDescriptorProto) bool {
2733	return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED
2734}
2735
2736// Is this field a scalar numeric type?
2737func isScalar(field *descriptor.FieldDescriptorProto) bool {
2738	if field.Type == nil {
2739		return false
2740	}
2741	switch *field.Type {
2742	case descriptor.FieldDescriptorProto_TYPE_DOUBLE,
2743		descriptor.FieldDescriptorProto_TYPE_FLOAT,
2744		descriptor.FieldDescriptorProto_TYPE_INT64,
2745		descriptor.FieldDescriptorProto_TYPE_UINT64,
2746		descriptor.FieldDescriptorProto_TYPE_INT32,
2747		descriptor.FieldDescriptorProto_TYPE_FIXED64,
2748		descriptor.FieldDescriptorProto_TYPE_FIXED32,
2749		descriptor.FieldDescriptorProto_TYPE_BOOL,
2750		descriptor.FieldDescriptorProto_TYPE_UINT32,
2751		descriptor.FieldDescriptorProto_TYPE_ENUM,
2752		descriptor.FieldDescriptorProto_TYPE_SFIXED32,
2753		descriptor.FieldDescriptorProto_TYPE_SFIXED64,
2754		descriptor.FieldDescriptorProto_TYPE_SINT32,
2755		descriptor.FieldDescriptorProto_TYPE_SINT64:
2756		return true
2757	default:
2758		return false
2759	}
2760}
2761
2762// badToUnderscore is the mapping function used to generate Go names from package names,
2763// which can be dotted in the input .proto file.  It replaces non-identifier characters such as
2764// dot or dash with underscore.
2765func badToUnderscore(r rune) rune {
2766	if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' {
2767		return r
2768	}
2769	return '_'
2770}
2771
2772// baseName returns the last path element of the name, with the last dotted suffix removed.
2773func baseName(name string) string {
2774	// First, find the last element
2775	if i := strings.LastIndex(name, "/"); i >= 0 {
2776		name = name[i+1:]
2777	}
2778	// Now drop the suffix
2779	if i := strings.LastIndex(name, "."); i >= 0 {
2780		name = name[0:i]
2781	}
2782	return name
2783}
2784
2785// The SourceCodeInfo message describes the location of elements of a parsed
2786// .proto file by way of a "path", which is a sequence of integers that
2787// describe the route from a FileDescriptorProto to the relevant submessage.
2788// The path alternates between a field number of a repeated field, and an index
2789// into that repeated field. The constants below define the field numbers that
2790// are used.
2791//
2792// See descriptor.proto for more information about this.
2793const (
2794	// tag numbers in FileDescriptorProto
2795	packagePath = 2 // package
2796	messagePath = 4 // message_type
2797	enumPath    = 5 // enum_type
2798	// tag numbers in DescriptorProto
2799	messageFieldPath   = 2 // field
2800	messageMessagePath = 3 // nested_type
2801	messageEnumPath    = 4 // enum_type
2802	messageOneofPath   = 8 // oneof_decl
2803	// tag numbers in EnumDescriptorProto
2804	enumValuePath = 2 // value
2805)
2806