blob: b9223b0b68cc51d02c7d8c899ae88bc67a04d606 [file] [log] [blame]
Damien Neil220c2022018-08-15 11:24:18 -07001// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// The protoc-gen-go binary is a protoc plugin to generate a Go protocol
6// buffer package.
7package main
8
9import (
Damien Neil7779e052018-09-07 14:14:06 -070010 "bytes"
11 "compress/gzip"
12 "crypto/sha256"
13 "encoding/hex"
14 "fmt"
15 "strconv"
16
17 "github.com/golang/protobuf/proto"
18 descpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
Damien Neil220c2022018-08-15 11:24:18 -070019 "google.golang.org/proto/protogen"
20)
21
22func main() {
23 protogen.Run(func(gen *protogen.Plugin) error {
24 for _, f := range gen.Files {
25 if !f.Generate {
26 continue
27 }
28 genFile(gen, f)
29 }
30 return nil
31 })
32}
33
34func genFile(gen *protogen.Plugin, f *protogen.File) {
Damien Neil082ce922018-09-06 10:23:53 -070035 g := gen.NewGeneratedFile(f.GeneratedFilenamePrefix+".pb.go", f.GoImportPath)
Damien Neil220c2022018-08-15 11:24:18 -070036 g.P("// Code generated by protoc-gen-go. DO NOT EDIT.")
Damien Neilabc6fc12018-08-23 14:39:30 -070037 g.P("// source: ", f.Desc.Path())
Damien Neil220c2022018-08-15 11:24:18 -070038 g.P()
Damien Neil082ce922018-09-06 10:23:53 -070039 g.P("package ", f.GoPackageName)
Damien Neilc7d07d92018-08-22 13:46:02 -070040 g.P()
41
42 for _, m := range f.Messages {
43 genMessage(gen, g, m)
44 }
Damien Neil220c2022018-08-15 11:24:18 -070045
Damien Neil7779e052018-09-07 14:14:06 -070046 genFileDescriptor(gen, g, f)
47}
48
49func genFileDescriptor(gen *protogen.Plugin, g *protogen.GeneratedFile, f *protogen.File) {
50 // Determine the name of the var holding the file descriptor:
51 //
52 // fileDescriptor_<hash of filename>
53 filenameHash := sha256.Sum256([]byte(f.Desc.Path()))
54 varName := fmt.Sprintf("fileDescriptor_%s", hex.EncodeToString(filenameHash[:8]))
55
56 // Trim the source_code_info from the descriptor.
57 // Marshal and gzip it.
58 descProto := proto.Clone(f.Proto).(*descpb.FileDescriptorProto)
59 descProto.SourceCodeInfo = nil
60 b, err := proto.Marshal(descProto)
61 if err != nil {
62 gen.Error(err)
63 return
64 }
65 var buf bytes.Buffer
66 w, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression)
67 w.Write(b)
68 w.Close()
69 b = buf.Bytes()
70
71 g.P("func init() { proto.RegisterFile(", strconv.Quote(f.Desc.Path()), ", ", varName, ") }")
72 g.P()
73 g.P("var ", varName, " = []byte{")
74 g.P("// ", len(b), " bytes of a gzipped FileDescriptorProto")
75 for len(b) > 0 {
76 n := 16
77 if n > len(b) {
78 n = len(b)
79 }
80
81 s := ""
82 for _, c := range b[:n] {
83 s += fmt.Sprintf("0x%02x,", c)
84 }
85 g.P(s)
86
87 b = b[n:]
88 }
89 g.P("}")
90 g.P()
Damien Neil220c2022018-08-15 11:24:18 -070091}
Damien Neilc7d07d92018-08-22 13:46:02 -070092
93func genMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, m *protogen.Message) {
94 g.P("type ", m.GoIdent, " struct {")
95 g.P("}")
96 g.P()
97
98 for _, nested := range m.Messages {
99 genMessage(gen, g, nested)
100 }
101}