...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
76 package description
77
78 import (
79 "bytes"
80 "compress/gzip"
81 "fmt"
82 "github.com/gogo/protobuf/gogoproto"
83 "github.com/gogo/protobuf/proto"
84 descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
85 "github.com/gogo/protobuf/protoc-gen-gogo/generator"
86 )
87
88 type plugin struct {
89 *generator.Generator
90 generator.PluginImports
91 }
92
93 func NewPlugin() *plugin {
94 return &plugin{}
95 }
96
97 func (p *plugin) Name() string {
98 return "description"
99 }
100
101 func (p *plugin) Init(g *generator.Generator) {
102 p.Generator = g
103 }
104
105 func (p *plugin) Generate(file *generator.FileDescriptor) {
106 used := false
107 localName := generator.FileName(file)
108
109 p.PluginImports = generator.NewPluginImports(p.Generator)
110 descriptorPkg := p.NewImport("github.com/gogo/protobuf/protoc-gen-gogo/descriptor")
111 protoPkg := p.NewImport("github.com/gogo/protobuf/proto")
112 gzipPkg := p.NewImport("compress/gzip")
113 bytesPkg := p.NewImport("bytes")
114 ioutilPkg := p.NewImport("io/ioutil")
115
116 for _, message := range file.Messages() {
117 if !gogoproto.HasDescription(file.FileDescriptorProto, message.DescriptorProto) {
118 continue
119 }
120 if message.DescriptorProto.GetOptions().GetMapEntry() {
121 continue
122 }
123 used = true
124 ccTypeName := generator.CamelCaseSlice(message.TypeName())
125 p.P(`func (this *`, ccTypeName, `) Description() (desc *`, descriptorPkg.Use(), `.FileDescriptorSet) {`)
126 p.In()
127 p.P(`return `, localName, `Description()`)
128 p.Out()
129 p.P(`}`)
130 }
131
132 if used {
133
134 p.P(`func `, localName, `Description() (desc *`, descriptorPkg.Use(), `.FileDescriptorSet) {`)
135 p.In()
136
137
138 ss := make([]*descriptor.SourceCodeInfo, 0)
139 for _, f := range p.Generator.AllFiles().GetFile() {
140 ss = append(ss, f.SourceCodeInfo)
141 f.SourceCodeInfo = nil
142 }
143 b, err := proto.Marshal(p.Generator.AllFiles())
144 if err != nil {
145 panic(err)
146 }
147 for i, f := range p.Generator.AllFiles().GetFile() {
148 f.SourceCodeInfo = ss[i]
149 }
150 p.P(`d := &`, descriptorPkg.Use(), `.FileDescriptorSet{}`)
151 var buf bytes.Buffer
152 w, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression)
153 w.Write(b)
154 w.Close()
155 b = buf.Bytes()
156 p.P("var gzipped = []byte{")
157 p.In()
158 p.P("// ", len(b), " bytes of a gzipped FileDescriptorSet")
159 for len(b) > 0 {
160 n := 16
161 if n > len(b) {
162 n = len(b)
163 }
164
165 s := ""
166 for _, c := range b[:n] {
167 s += fmt.Sprintf("0x%02x,", c)
168 }
169 p.P(s)
170
171 b = b[n:]
172 }
173 p.Out()
174 p.P("}")
175 p.P(`r := `, bytesPkg.Use(), `.NewReader(gzipped)`)
176 p.P(`gzipr, err := `, gzipPkg.Use(), `.NewReader(r)`)
177 p.P(`if err != nil {`)
178 p.In()
179 p.P(`panic(err)`)
180 p.Out()
181 p.P(`}`)
182 p.P(`ungzipped, err := `, ioutilPkg.Use(), `.ReadAll(gzipr)`)
183 p.P(`if err != nil {`)
184 p.In()
185 p.P(`panic(err)`)
186 p.Out()
187 p.P(`}`)
188 p.P(`if err := `, protoPkg.Use(), `.Unmarshal(ungzipped, d); err != nil {`)
189 p.In()
190 p.P(`panic(err)`)
191 p.Out()
192 p.P(`}`)
193 p.P(`return d`)
194 p.Out()
195 p.P(`}`)
196 }
197 }
198
199 func init() {
200 generator.RegisterPlugin(NewPlugin())
201 }
202
View as plain text