1
2
3
4
5 package filedesc
6
7 import (
8 "fmt"
9 "math"
10 "sort"
11 "sync"
12
13 "google.golang.org/protobuf/internal/genid"
14
15 "google.golang.org/protobuf/encoding/protowire"
16 "google.golang.org/protobuf/internal/descfmt"
17 "google.golang.org/protobuf/internal/errors"
18 "google.golang.org/protobuf/internal/pragma"
19 "google.golang.org/protobuf/reflect/protoreflect"
20 )
21
22 type FileImports []protoreflect.FileImport
23
24 func (p *FileImports) Len() int { return len(*p) }
25 func (p *FileImports) Get(i int) protoreflect.FileImport { return (*p)[i] }
26 func (p *FileImports) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
27 func (p *FileImports) ProtoInternal(pragma.DoNotImplement) {}
28
29 type Names struct {
30 List []protoreflect.Name
31 once sync.Once
32 has map[protoreflect.Name]int
33 }
34
35 func (p *Names) Len() int { return len(p.List) }
36 func (p *Names) Get(i int) protoreflect.Name { return p.List[i] }
37 func (p *Names) Has(s protoreflect.Name) bool { return p.lazyInit().has[s] > 0 }
38 func (p *Names) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
39 func (p *Names) ProtoInternal(pragma.DoNotImplement) {}
40 func (p *Names) lazyInit() *Names {
41 p.once.Do(func() {
42 if len(p.List) > 0 {
43 p.has = make(map[protoreflect.Name]int, len(p.List))
44 for _, s := range p.List {
45 p.has[s] = p.has[s] + 1
46 }
47 }
48 })
49 return p
50 }
51
52
53
54 func (p *Names) CheckValid() error {
55 for s, n := range p.lazyInit().has {
56 switch {
57 case n > 1:
58 return errors.New("duplicate name: %q", s)
59 case false && !s.IsValid():
60
61
62 return errors.New("invalid name: %q", s)
63 }
64 }
65 return nil
66 }
67
68 type EnumRanges struct {
69 List [][2]protoreflect.EnumNumber
70 once sync.Once
71 sorted [][2]protoreflect.EnumNumber
72 }
73
74 func (p *EnumRanges) Len() int { return len(p.List) }
75 func (p *EnumRanges) Get(i int) [2]protoreflect.EnumNumber { return p.List[i] }
76 func (p *EnumRanges) Has(n protoreflect.EnumNumber) bool {
77 for ls := p.lazyInit().sorted; len(ls) > 0; {
78 i := len(ls) / 2
79 switch r := enumRange(ls[i]); {
80 case n < r.Start():
81 ls = ls[:i]
82 case n > r.End():
83 ls = ls[i+1:]
84 default:
85 return true
86 }
87 }
88 return false
89 }
90 func (p *EnumRanges) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
91 func (p *EnumRanges) ProtoInternal(pragma.DoNotImplement) {}
92 func (p *EnumRanges) lazyInit() *EnumRanges {
93 p.once.Do(func() {
94 p.sorted = append(p.sorted, p.List...)
95 sort.Slice(p.sorted, func(i, j int) bool {
96 return p.sorted[i][0] < p.sorted[j][0]
97 })
98 })
99 return p
100 }
101
102
103
104 func (p *EnumRanges) CheckValid() error {
105 var rp enumRange
106 for i, r := range p.lazyInit().sorted {
107 r := enumRange(r)
108 switch {
109 case !(r.Start() <= r.End()):
110 return errors.New("invalid range: %v", r)
111 case !(rp.End() < r.Start()) && i > 0:
112 return errors.New("overlapping ranges: %v with %v", rp, r)
113 }
114 rp = r
115 }
116 return nil
117 }
118
119 type enumRange [2]protoreflect.EnumNumber
120
121 func (r enumRange) Start() protoreflect.EnumNumber { return r[0] }
122 func (r enumRange) End() protoreflect.EnumNumber { return r[1] }
123 func (r enumRange) String() string {
124 if r.Start() == r.End() {
125 return fmt.Sprintf("%d", r.Start())
126 }
127 return fmt.Sprintf("%d to %d", r.Start(), r.End())
128 }
129
130 type FieldRanges struct {
131 List [][2]protoreflect.FieldNumber
132 once sync.Once
133 sorted [][2]protoreflect.FieldNumber
134 }
135
136 func (p *FieldRanges) Len() int { return len(p.List) }
137 func (p *FieldRanges) Get(i int) [2]protoreflect.FieldNumber { return p.List[i] }
138 func (p *FieldRanges) Has(n protoreflect.FieldNumber) bool {
139 for ls := p.lazyInit().sorted; len(ls) > 0; {
140 i := len(ls) / 2
141 switch r := fieldRange(ls[i]); {
142 case n < r.Start():
143 ls = ls[:i]
144 case n > r.End():
145 ls = ls[i+1:]
146 default:
147 return true
148 }
149 }
150 return false
151 }
152 func (p *FieldRanges) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
153 func (p *FieldRanges) ProtoInternal(pragma.DoNotImplement) {}
154 func (p *FieldRanges) lazyInit() *FieldRanges {
155 p.once.Do(func() {
156 p.sorted = append(p.sorted, p.List...)
157 sort.Slice(p.sorted, func(i, j int) bool {
158 return p.sorted[i][0] < p.sorted[j][0]
159 })
160 })
161 return p
162 }
163
164
165
166 func (p *FieldRanges) CheckValid(isMessageSet bool) error {
167 var rp fieldRange
168 for i, r := range p.lazyInit().sorted {
169 r := fieldRange(r)
170 switch {
171 case !isValidFieldNumber(r.Start(), isMessageSet):
172 return errors.New("invalid field number: %d", r.Start())
173 case !isValidFieldNumber(r.End(), isMessageSet):
174 return errors.New("invalid field number: %d", r.End())
175 case !(r.Start() <= r.End()):
176 return errors.New("invalid range: %v", r)
177 case !(rp.End() < r.Start()) && i > 0:
178 return errors.New("overlapping ranges: %v with %v", rp, r)
179 }
180 rp = r
181 }
182 return nil
183 }
184
185
186
187
188 func isValidFieldNumber(n protoreflect.FieldNumber, isMessageSet bool) bool {
189 return protowire.MinValidNumber <= n && (n <= protowire.MaxValidNumber || isMessageSet)
190 }
191
192
193 func (p *FieldRanges) CheckOverlap(q *FieldRanges) error {
194 rps := p.lazyInit().sorted
195 rqs := q.lazyInit().sorted
196 for pi, qi := 0, 0; pi < len(rps) && qi < len(rqs); {
197 rp := fieldRange(rps[pi])
198 rq := fieldRange(rqs[qi])
199 if !(rp.End() < rq.Start() || rq.End() < rp.Start()) {
200 return errors.New("overlapping ranges: %v with %v", rp, rq)
201 }
202 if rp.Start() < rq.Start() {
203 pi++
204 } else {
205 qi++
206 }
207 }
208 return nil
209 }
210
211 type fieldRange [2]protoreflect.FieldNumber
212
213 func (r fieldRange) Start() protoreflect.FieldNumber { return r[0] }
214 func (r fieldRange) End() protoreflect.FieldNumber { return r[1] - 1 }
215 func (r fieldRange) String() string {
216 if r.Start() == r.End() {
217 return fmt.Sprintf("%d", r.Start())
218 }
219 return fmt.Sprintf("%d to %d", r.Start(), r.End())
220 }
221
222 type FieldNumbers struct {
223 List []protoreflect.FieldNumber
224 once sync.Once
225 has map[protoreflect.FieldNumber]struct{}
226 }
227
228 func (p *FieldNumbers) Len() int { return len(p.List) }
229 func (p *FieldNumbers) Get(i int) protoreflect.FieldNumber { return p.List[i] }
230 func (p *FieldNumbers) Has(n protoreflect.FieldNumber) bool {
231 p.once.Do(func() {
232 if len(p.List) > 0 {
233 p.has = make(map[protoreflect.FieldNumber]struct{}, len(p.List))
234 for _, n := range p.List {
235 p.has[n] = struct{}{}
236 }
237 }
238 })
239 _, ok := p.has[n]
240 return ok
241 }
242 func (p *FieldNumbers) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
243 func (p *FieldNumbers) ProtoInternal(pragma.DoNotImplement) {}
244
245 type OneofFields struct {
246 List []protoreflect.FieldDescriptor
247 once sync.Once
248 byName map[protoreflect.Name]protoreflect.FieldDescriptor
249 byJSON map[string]protoreflect.FieldDescriptor
250 byText map[string]protoreflect.FieldDescriptor
251 byNum map[protoreflect.FieldNumber]protoreflect.FieldDescriptor
252 }
253
254 func (p *OneofFields) Len() int { return len(p.List) }
255 func (p *OneofFields) Get(i int) protoreflect.FieldDescriptor { return p.List[i] }
256 func (p *OneofFields) ByName(s protoreflect.Name) protoreflect.FieldDescriptor {
257 return p.lazyInit().byName[s]
258 }
259 func (p *OneofFields) ByJSONName(s string) protoreflect.FieldDescriptor {
260 return p.lazyInit().byJSON[s]
261 }
262 func (p *OneofFields) ByTextName(s string) protoreflect.FieldDescriptor {
263 return p.lazyInit().byText[s]
264 }
265 func (p *OneofFields) ByNumber(n protoreflect.FieldNumber) protoreflect.FieldDescriptor {
266 return p.lazyInit().byNum[n]
267 }
268 func (p *OneofFields) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) }
269 func (p *OneofFields) ProtoInternal(pragma.DoNotImplement) {}
270
271 func (p *OneofFields) lazyInit() *OneofFields {
272 p.once.Do(func() {
273 if len(p.List) > 0 {
274 p.byName = make(map[protoreflect.Name]protoreflect.FieldDescriptor, len(p.List))
275 p.byJSON = make(map[string]protoreflect.FieldDescriptor, len(p.List))
276 p.byText = make(map[string]protoreflect.FieldDescriptor, len(p.List))
277 p.byNum = make(map[protoreflect.FieldNumber]protoreflect.FieldDescriptor, len(p.List))
278 for _, f := range p.List {
279
280 p.byName[f.Name()] = f
281 p.byJSON[f.JSONName()] = f
282 p.byText[f.TextName()] = f
283 p.byNum[f.Number()] = f
284 }
285 }
286 })
287 return p
288 }
289
290 type SourceLocations struct {
291
292
293
294 List []protoreflect.SourceLocation
295
296
297
298
299 File protoreflect.FileDescriptor
300
301 once sync.Once
302 byPath map[pathKey]int
303 }
304
305 func (p *SourceLocations) Len() int { return len(p.List) }
306 func (p *SourceLocations) Get(i int) protoreflect.SourceLocation { return p.lazyInit().List[i] }
307 func (p *SourceLocations) byKey(k pathKey) protoreflect.SourceLocation {
308 if i, ok := p.lazyInit().byPath[k]; ok {
309 return p.List[i]
310 }
311 return protoreflect.SourceLocation{}
312 }
313 func (p *SourceLocations) ByPath(path protoreflect.SourcePath) protoreflect.SourceLocation {
314 return p.byKey(newPathKey(path))
315 }
316 func (p *SourceLocations) ByDescriptor(desc protoreflect.Descriptor) protoreflect.SourceLocation {
317 if p.File != nil && desc != nil && p.File != desc.ParentFile() {
318 return protoreflect.SourceLocation{}
319 }
320 var pathArr [16]int32
321 path := pathArr[:0]
322 for {
323 switch desc.(type) {
324 case protoreflect.FileDescriptor:
325
326 for i, j := 0, len(path)-1; i < j; i, j = i+1, j-1 {
327 path[i], path[j] = path[j], path[i]
328 }
329 return p.byKey(newPathKey(path))
330 case protoreflect.MessageDescriptor:
331 path = append(path, int32(desc.Index()))
332 desc = desc.Parent()
333 switch desc.(type) {
334 case protoreflect.FileDescriptor:
335 path = append(path, int32(genid.FileDescriptorProto_MessageType_field_number))
336 case protoreflect.MessageDescriptor:
337 path = append(path, int32(genid.DescriptorProto_NestedType_field_number))
338 default:
339 return protoreflect.SourceLocation{}
340 }
341 case protoreflect.FieldDescriptor:
342 isExtension := desc.(protoreflect.FieldDescriptor).IsExtension()
343 path = append(path, int32(desc.Index()))
344 desc = desc.Parent()
345 if isExtension {
346 switch desc.(type) {
347 case protoreflect.FileDescriptor:
348 path = append(path, int32(genid.FileDescriptorProto_Extension_field_number))
349 case protoreflect.MessageDescriptor:
350 path = append(path, int32(genid.DescriptorProto_Extension_field_number))
351 default:
352 return protoreflect.SourceLocation{}
353 }
354 } else {
355 switch desc.(type) {
356 case protoreflect.MessageDescriptor:
357 path = append(path, int32(genid.DescriptorProto_Field_field_number))
358 default:
359 return protoreflect.SourceLocation{}
360 }
361 }
362 case protoreflect.OneofDescriptor:
363 path = append(path, int32(desc.Index()))
364 desc = desc.Parent()
365 switch desc.(type) {
366 case protoreflect.MessageDescriptor:
367 path = append(path, int32(genid.DescriptorProto_OneofDecl_field_number))
368 default:
369 return protoreflect.SourceLocation{}
370 }
371 case protoreflect.EnumDescriptor:
372 path = append(path, int32(desc.Index()))
373 desc = desc.Parent()
374 switch desc.(type) {
375 case protoreflect.FileDescriptor:
376 path = append(path, int32(genid.FileDescriptorProto_EnumType_field_number))
377 case protoreflect.MessageDescriptor:
378 path = append(path, int32(genid.DescriptorProto_EnumType_field_number))
379 default:
380 return protoreflect.SourceLocation{}
381 }
382 case protoreflect.EnumValueDescriptor:
383 path = append(path, int32(desc.Index()))
384 desc = desc.Parent()
385 switch desc.(type) {
386 case protoreflect.EnumDescriptor:
387 path = append(path, int32(genid.EnumDescriptorProto_Value_field_number))
388 default:
389 return protoreflect.SourceLocation{}
390 }
391 case protoreflect.ServiceDescriptor:
392 path = append(path, int32(desc.Index()))
393 desc = desc.Parent()
394 switch desc.(type) {
395 case protoreflect.FileDescriptor:
396 path = append(path, int32(genid.FileDescriptorProto_Service_field_number))
397 default:
398 return protoreflect.SourceLocation{}
399 }
400 case protoreflect.MethodDescriptor:
401 path = append(path, int32(desc.Index()))
402 desc = desc.Parent()
403 switch desc.(type) {
404 case protoreflect.ServiceDescriptor:
405 path = append(path, int32(genid.ServiceDescriptorProto_Method_field_number))
406 default:
407 return protoreflect.SourceLocation{}
408 }
409 default:
410 return protoreflect.SourceLocation{}
411 }
412 }
413 }
414 func (p *SourceLocations) lazyInit() *SourceLocations {
415 p.once.Do(func() {
416 if len(p.List) > 0 {
417
418 pathIdxs := make(map[pathKey][]int, len(p.List))
419 for i, l := range p.List {
420 k := newPathKey(l.Path)
421 pathIdxs[k] = append(pathIdxs[k], i)
422 }
423
424
425 p.byPath = make(map[pathKey]int, len(p.List))
426 for k, idxs := range pathIdxs {
427 for i := 0; i < len(idxs)-1; i++ {
428 p.List[idxs[i]].Next = idxs[i+1]
429 }
430 p.List[idxs[len(idxs)-1]].Next = 0
431 p.byPath[k] = idxs[0]
432 }
433 }
434 })
435 return p
436 }
437 func (p *SourceLocations) ProtoInternal(pragma.DoNotImplement) {}
438
439
440 type pathKey struct {
441 arr [16]uint8
442 str string
443 }
444
445 func newPathKey(p protoreflect.SourcePath) (k pathKey) {
446 if len(p) < len(k.arr) {
447 for i, ps := range p {
448 if ps < 0 || math.MaxUint8 <= ps {
449 return pathKey{str: p.String()}
450 }
451 k.arr[i] = uint8(ps)
452 }
453 k.arr[len(k.arr)-1] = uint8(len(p))
454 return k
455 }
456 return pathKey{str: p.String()}
457 }
458
View as plain text