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