OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / github.com / golang / protobuf / protoc-gen-go / generator / generator.go
1 // Go support for Protocol Buffers - Google's data interchange format
2 //
3 // Copyright 2010 The Go Authors.  All rights reserved.
4 // https://github.com/golang/protobuf
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met:
9 //
10 //     * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 //     * Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following disclaimer
14 // in the documentation and/or other materials provided with the
15 // distribution.
16 //     * Neither the name of Google Inc. nor the names of its
17 // contributors may be used to endorse or promote products derived from
18 // this software without specific prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32 /*
33         The code generator for the plugin for the Google protocol buffer compiler.
34         It generates Go code from the protocol buffer description files read by the
35         main routine.
36 */
37 package generator
38
39 import (
40         "bufio"
41         "bytes"
42         "compress/gzip"
43         "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).
65 const generatedCodeVersion = 2
66
67 // A Plugin provides functionality to add to the output during Go code generation,
68 // such as to produce RPC stubs.
69 type 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
83 var 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.
87 func 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.
98 type 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.
103 func (c *common) PackageName() string { return uniquePackageOf(c.file) }
104
105 func (c *common) File() *descriptor.FileDescriptorProto { return c.file }
106
107 func fileIsProto3(file *descriptor.FileDescriptorProto) bool {
108         return file.GetSyntax() == "proto3"
109 }
110
111 func (c *common) proto3() bool { return fileIsProto3(c.file) }
112
113 // Descriptor represents a protocol buffer message.
114 type 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.
129 func (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.
148 type 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.
159 func (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... .
178 func (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.
188 func (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.
200 type 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.
208 func (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.
223 func (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.
234 type ImportedDescriptor struct {
235         common
236         o Object
237 }
238
239 func (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.
244 type 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.
265 func (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.
270 func (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).
276 func (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.
302 func (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.
317 func (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
336 func (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.
341 type 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
347 type messageSymbol struct {
348         sym                         string
349         hasExtensions, isMessageSet bool
350         hasOneof                    bool
351         getters                     []getterSymbol
352 }
353
354 type 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
361 func (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
501 type enumSymbol struct {
502         name   string
503         proto3 bool // Whether this came from a proto3 file.
504 }
505
506 func (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
518 type 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
524 func (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.
533 type 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).
543 func 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.
552 type 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.
578 func 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.
587 func (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.
594 func (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.
603 func (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.
648 func (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.
657 var 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.
661 var 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.
666 func 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
682 var 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.
712 func (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.
736 func (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
785 AllFiles:
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.
807 func (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
845 func (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
860 func (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
876 func 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
913 func 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
922 func 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
932 func 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
948 func 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.
964 func 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.
973 func 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
992 func 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.
1009 func (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.
1032 func (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.
1075 func (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.
1109 func (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.
1114 func (g *Generator) In() { g.indent += "\t" }
1115
1116 // Out unindents the output one tab stop.
1117 func (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.
1124 func (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.
1151 func (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.
1158 func (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.
1170 func (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
1239 func (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.
1289 func (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
1303 func (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.
1308 func (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
1318 func (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
1365 func (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.
1392 func (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.
1492 func (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
1599 func 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.
1616 func (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.
1622 func (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
1627 func (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
1684 func (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.
1695 var 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.
1708 var 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.
1729 func (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(unescape(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
2511 var escapeChars = [256]byte{
2512         'a': '\a', 'b': '\b', 'f': '\f', 'n': '\n', 'r': '\r', 't': '\t', 'v': '\v', '\\': '\\', '"': '"', '\'': '\'', '?': '?',
2513 }
2514
2515 // unescape reverses the "C" escaping that protoc does for default values of bytes fields.
2516 // It is best effort in that it effectively ignores malformed input. Seemingly invalid escape
2517 // sequences are conveyed, unmodified, into the decoded result.
2518 func unescape(s string) string {
2519         // NB: Sadly, we can't use strconv.Unquote because protoc will escape both
2520         // single and double quotes, but strconv.Unquote only allows one or the
2521         // other (based on actual surrounding quotes of its input argument).
2522
2523         var out []byte
2524         for len(s) > 0 {
2525                 // regular character, or too short to be valid escape
2526                 if s[0] != '\\' || len(s) < 2 {
2527                         out = append(out, s[0])
2528                         s = s[1:]
2529                 } else if c := escapeChars[s[1]]; c != 0 {
2530                         // escape sequence
2531                         out = append(out, c)
2532                         s = s[2:]
2533                 } else if s[1] == 'x' || s[1] == 'X' {
2534                         // hex escape, e.g. "\x80
2535                         if len(s) < 4 {
2536                                 // too short to be valid
2537                                 out = append(out, s[:2]...)
2538                                 s = s[2:]
2539                                 continue
2540                         }
2541                         v, err := strconv.ParseUint(s[2:4], 16, 8)
2542                         if err != nil {
2543                                 out = append(out, s[:4]...)
2544                         } else {
2545                                 out = append(out, byte(v))
2546                         }
2547                         s = s[4:]
2548                 } else if '0' <= s[1] && s[1] <= '7' {
2549                         // octal escape, can vary from 1 to 3 octal digits; e.g., "\0" "\40" or "\164"
2550                         // so consume up to 2 more bytes or up to end-of-string
2551                         n := len(s[1:]) - len(strings.TrimLeft(s[1:], "01234567"))
2552                         if n > 3 {
2553                                 n = 3
2554                         }
2555                         v, err := strconv.ParseUint(s[1:1+n], 8, 8)
2556                         if err != nil {
2557                                 out = append(out, s[:1+n]...)
2558                         } else {
2559                                 out = append(out, byte(v))
2560                         }
2561                         s = s[1+n:]
2562                 } else {
2563                         // bad escape, just propagate the slash as-is
2564                         out = append(out, s[0])
2565                         s = s[1:]
2566                 }
2567         }
2568
2569         return string(out)
2570 }
2571
2572 func (g *Generator) generateExtension(ext *ExtensionDescriptor) {
2573         ccTypeName := ext.DescName()
2574
2575         extObj := g.ObjectNamed(*ext.Extendee)
2576         var extDesc *Descriptor
2577         if id, ok := extObj.(*ImportedDescriptor); ok {
2578                 // This is extending a publicly imported message.
2579                 // We need the underlying type for goTag.
2580                 extDesc = id.o.(*Descriptor)
2581         } else {
2582                 extDesc = extObj.(*Descriptor)
2583         }
2584         extendedType := "*" + g.TypeName(extObj) // always use the original
2585         field := ext.FieldDescriptorProto
2586         fieldType, wireType := g.GoType(ext.parent, field)
2587         tag := g.goTag(extDesc, field, wireType)
2588         g.RecordTypeUse(*ext.Extendee)
2589         if n := ext.FieldDescriptorProto.TypeName; n != nil {
2590                 // foreign extension type
2591                 g.RecordTypeUse(*n)
2592         }
2593
2594         typeName := ext.TypeName()
2595
2596         // Special case for proto2 message sets: If this extension is extending
2597         // proto2_bridge.MessageSet, and its final name component is "message_set_extension",
2598         // then drop that last component.
2599         mset := false
2600         if extendedType == "*proto2_bridge.MessageSet" && typeName[len(typeName)-1] == "message_set_extension" {
2601                 typeName = typeName[:len(typeName)-1]
2602                 mset = true
2603         }
2604
2605         // For text formatting, the package must be exactly what the .proto file declares,
2606         // ignoring overrides such as the go_package option, and with no dot/underscore mapping.
2607         extName := strings.Join(typeName, ".")
2608         if g.file.Package != nil {
2609                 extName = *g.file.Package + "." + extName
2610         }
2611
2612         g.P("var ", ccTypeName, " = &", g.Pkg["proto"], ".ExtensionDesc{")
2613         g.In()
2614         g.P("ExtendedType: (", extendedType, ")(nil),")
2615         g.P("ExtensionType: (", fieldType, ")(nil),")
2616         g.P("Field: ", field.Number, ",")
2617         g.P(`Name: "`, extName, `",`)
2618         g.P("Tag: ", tag, ",")
2619         g.P(`Filename: "`, g.file.GetName(), `",`)
2620
2621         g.Out()
2622         g.P("}")
2623         g.P()
2624
2625         if mset {
2626                 // Generate a bit more code to register with message_set.go.
2627                 g.addInitf("%s.RegisterMessageSetType((%s)(nil), %d, %q)", g.Pkg["proto"], fieldType, *field.Number, extName)
2628         }
2629
2630         g.file.addExport(ext, constOrVarSymbol{ccTypeName, "var", ""})
2631 }
2632
2633 func (g *Generator) generateInitFunction() {
2634         for _, enum := range g.file.enum {
2635                 g.generateEnumRegistration(enum)
2636         }
2637         for _, d := range g.file.desc {
2638                 for _, ext := range d.ext {
2639                         g.generateExtensionRegistration(ext)
2640                 }
2641         }
2642         for _, ext := range g.file.ext {
2643                 g.generateExtensionRegistration(ext)
2644         }
2645         if len(g.init) == 0 {
2646                 return
2647         }
2648         g.P("func init() {")
2649         g.In()
2650         for _, l := range g.init {
2651                 g.P(l)
2652         }
2653         g.Out()
2654         g.P("}")
2655         g.init = nil
2656 }
2657
2658 func (g *Generator) generateFileDescriptor(file *FileDescriptor) {
2659         // Make a copy and trim source_code_info data.
2660         // TODO: Trim this more when we know exactly what we need.
2661         pb := proto.Clone(file.FileDescriptorProto).(*descriptor.FileDescriptorProto)
2662         pb.SourceCodeInfo = nil
2663
2664         b, err := proto.Marshal(pb)
2665         if err != nil {
2666                 g.Fail(err.Error())
2667         }
2668
2669         var buf bytes.Buffer
2670         w, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression)
2671         w.Write(b)
2672         w.Close()
2673         b = buf.Bytes()
2674
2675         v := file.VarName()
2676         g.P()
2677         g.P("func init() { ", g.Pkg["proto"], ".RegisterFile(", strconv.Quote(*file.Name), ", ", v, ") }")
2678         g.P("var ", v, " = []byte{")
2679         g.In()
2680         g.P("// ", len(b), " bytes of a gzipped FileDescriptorProto")
2681         for len(b) > 0 {
2682                 n := 16
2683                 if n > len(b) {
2684                         n = len(b)
2685                 }
2686
2687                 s := ""
2688                 for _, c := range b[:n] {
2689                         s += fmt.Sprintf("0x%02x,", c)
2690                 }
2691                 g.P(s)
2692
2693                 b = b[n:]
2694         }
2695         g.Out()
2696         g.P("}")
2697 }
2698
2699 func (g *Generator) generateEnumRegistration(enum *EnumDescriptor) {
2700         // // We always print the full (proto-world) package name here.
2701         pkg := enum.File().GetPackage()
2702         if pkg != "" {
2703                 pkg += "."
2704         }
2705         // The full type name
2706         typeName := enum.TypeName()
2707         // The full type name, CamelCased.
2708         ccTypeName := CamelCaseSlice(typeName)
2709         g.addInitf("%s.RegisterEnum(%q, %[3]s_name, %[3]s_value)", g.Pkg["proto"], pkg+ccTypeName, ccTypeName)
2710 }
2711
2712 func (g *Generator) generateExtensionRegistration(ext *ExtensionDescriptor) {
2713         g.addInitf("%s.RegisterExtension(%s)", g.Pkg["proto"], ext.DescName())
2714 }
2715
2716 // And now lots of helper functions.
2717
2718 // Is c an ASCII lower-case letter?
2719 func isASCIILower(c byte) bool {
2720         return 'a' <= c && c <= 'z'
2721 }
2722
2723 // Is c an ASCII digit?
2724 func isASCIIDigit(c byte) bool {
2725         return '0' <= c && c <= '9'
2726 }
2727
2728 // CamelCase returns the CamelCased name.
2729 // If there is an interior underscore followed by a lower case letter,
2730 // drop the underscore and convert the letter to upper case.
2731 // There is a remote possibility of this rewrite causing a name collision,
2732 // but it's so remote we're prepared to pretend it's nonexistent - since the
2733 // C++ generator lowercases names, it's extremely unlikely to have two fields
2734 // with different capitalizations.
2735 // In short, _my_field_name_2 becomes XMyFieldName_2.
2736 func CamelCase(s string) string {
2737         if s == "" {
2738                 return ""
2739         }
2740         t := make([]byte, 0, 32)
2741         i := 0
2742         if s[0] == '_' {
2743                 // Need a capital letter; drop the '_'.
2744                 t = append(t, 'X')
2745                 i++
2746         }
2747         // Invariant: if the next letter is lower case, it must be converted
2748         // to upper case.
2749         // That is, we process a word at a time, where words are marked by _ or
2750         // upper case letter. Digits are treated as words.
2751         for ; i < len(s); i++ {
2752                 c := s[i]
2753                 if c == '_' && i+1 < len(s) && isASCIILower(s[i+1]) {
2754                         continue // Skip the underscore in s.
2755                 }
2756                 if isASCIIDigit(c) {
2757                         t = append(t, c)
2758                         continue
2759                 }
2760                 // Assume we have a letter now - if not, it's a bogus identifier.
2761                 // The next word is a sequence of characters that must start upper case.
2762                 if isASCIILower(c) {
2763                         c ^= ' ' // Make it a capital letter.
2764                 }
2765                 t = append(t, c) // Guaranteed not lower case.
2766                 // Accept lower case sequence that follows.
2767                 for i+1 < len(s) && isASCIILower(s[i+1]) {
2768                         i++
2769                         t = append(t, s[i])
2770                 }
2771         }
2772         return string(t)
2773 }
2774
2775 // CamelCaseSlice is like CamelCase, but the argument is a slice of strings to
2776 // be joined with "_".
2777 func CamelCaseSlice(elem []string) string { return CamelCase(strings.Join(elem, "_")) }
2778
2779 // dottedSlice turns a sliced name into a dotted name.
2780 func dottedSlice(elem []string) string { return strings.Join(elem, ".") }
2781
2782 // Is this field optional?
2783 func isOptional(field *descriptor.FieldDescriptorProto) bool {
2784         return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_OPTIONAL
2785 }
2786
2787 // Is this field required?
2788 func isRequired(field *descriptor.FieldDescriptorProto) bool {
2789         return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REQUIRED
2790 }
2791
2792 // Is this field repeated?
2793 func isRepeated(field *descriptor.FieldDescriptorProto) bool {
2794         return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED
2795 }
2796
2797 // Is this field a scalar numeric type?
2798 func isScalar(field *descriptor.FieldDescriptorProto) bool {
2799         if field.Type == nil {
2800                 return false
2801         }
2802         switch *field.Type {
2803         case descriptor.FieldDescriptorProto_TYPE_DOUBLE,
2804                 descriptor.FieldDescriptorProto_TYPE_FLOAT,
2805                 descriptor.FieldDescriptorProto_TYPE_INT64,
2806                 descriptor.FieldDescriptorProto_TYPE_UINT64,
2807                 descriptor.FieldDescriptorProto_TYPE_INT32,
2808                 descriptor.FieldDescriptorProto_TYPE_FIXED64,
2809                 descriptor.FieldDescriptorProto_TYPE_FIXED32,
2810                 descriptor.FieldDescriptorProto_TYPE_BOOL,
2811                 descriptor.FieldDescriptorProto_TYPE_UINT32,
2812                 descriptor.FieldDescriptorProto_TYPE_ENUM,
2813                 descriptor.FieldDescriptorProto_TYPE_SFIXED32,
2814                 descriptor.FieldDescriptorProto_TYPE_SFIXED64,
2815                 descriptor.FieldDescriptorProto_TYPE_SINT32,
2816                 descriptor.FieldDescriptorProto_TYPE_SINT64:
2817                 return true
2818         default:
2819                 return false
2820         }
2821 }
2822
2823 // badToUnderscore is the mapping function used to generate Go names from package names,
2824 // which can be dotted in the input .proto file.  It replaces non-identifier characters such as
2825 // dot or dash with underscore.
2826 func badToUnderscore(r rune) rune {
2827         if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' {
2828                 return r
2829         }
2830         return '_'
2831 }
2832
2833 // baseName returns the last path element of the name, with the last dotted suffix removed.
2834 func baseName(name string) string {
2835         // First, find the last element
2836         if i := strings.LastIndex(name, "/"); i >= 0 {
2837                 name = name[i+1:]
2838         }
2839         // Now drop the suffix
2840         if i := strings.LastIndex(name, "."); i >= 0 {
2841                 name = name[0:i]
2842         }
2843         return name
2844 }
2845
2846 // The SourceCodeInfo message describes the location of elements of a parsed
2847 // .proto file by way of a "path", which is a sequence of integers that
2848 // describe the route from a FileDescriptorProto to the relevant submessage.
2849 // The path alternates between a field number of a repeated field, and an index
2850 // into that repeated field. The constants below define the field numbers that
2851 // are used.
2852 //
2853 // See descriptor.proto for more information about this.
2854 const (
2855         // tag numbers in FileDescriptorProto
2856         packagePath = 2 // package
2857         messagePath = 4 // message_type
2858         enumPath    = 5 // enum_type
2859         // tag numbers in DescriptorProto
2860         messageFieldPath   = 2 // field
2861         messageMessagePath = 3 // nested_type
2862         messageEnumPath    = 4 // enum_type
2863         messageOneofPath   = 8 // oneof_decl
2864         // tag numbers in EnumDescriptorProto
2865         enumValuePath = 2 // value
2866 )