blob: 04530dc67dee9b1ccc8ce15670b17161b77c89fc [file] [log] [blame]
Zack Williamse940c7a2019-08-21 14:25:39 -07001package protoparse
2
3import (
4 "bytes"
5 "fmt"
6 "math"
7
8 "github.com/golang/protobuf/proto"
9 dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
10
11 "github.com/jhump/protoreflect/desc"
12 "github.com/jhump/protoreflect/desc/internal"
13 "github.com/jhump/protoreflect/dynamic"
14)
15
16// NB: To process options, we need descriptors, but we may not have rich
17// descriptors when trying to interpret options for unlinked parsed files.
18// So we define minimal interfaces that can be backed by both rich descriptors
19// as well as their poorer cousins, plain ol' descriptor protos.
20
21type descriptorish interface {
22 GetFile() fileDescriptorish
23 GetFullyQualifiedName() string
24 AsProto() proto.Message
25}
26
27type fileDescriptorish interface {
28 descriptorish
29 GetFileOptions() *dpb.FileOptions
30 GetPackage() string
31 FindSymbol(name string) desc.Descriptor
32 GetPublicDependencies() []fileDescriptorish
33 GetDependencies() []fileDescriptorish
34 GetMessageTypes() []msgDescriptorish
35 GetExtensions() []fldDescriptorish
36 GetEnumTypes() []enumDescriptorish
37 GetServices() []svcDescriptorish
38}
39
40type msgDescriptorish interface {
41 descriptorish
42 GetMessageOptions() *dpb.MessageOptions
43 GetFields() []fldDescriptorish
44 GetOneOfs() []oneofDescriptorish
45 GetExtensionRanges() []extRangeDescriptorish
46 GetNestedMessageTypes() []msgDescriptorish
47 GetNestedExtensions() []fldDescriptorish
48 GetNestedEnumTypes() []enumDescriptorish
49}
50
51type fldDescriptorish interface {
52 descriptorish
53 GetFieldOptions() *dpb.FieldOptions
54 GetMessageType() *desc.MessageDescriptor
55 GetEnumType() *desc.EnumDescriptor
56 AsFieldDescriptorProto() *dpb.FieldDescriptorProto
57}
58
59type oneofDescriptorish interface {
60 descriptorish
61 GetOneOfOptions() *dpb.OneofOptions
62}
63
64type enumDescriptorish interface {
65 descriptorish
66 GetEnumOptions() *dpb.EnumOptions
67 GetValues() []enumValDescriptorish
68}
69
70type enumValDescriptorish interface {
71 descriptorish
72 GetEnumValueOptions() *dpb.EnumValueOptions
73}
74
75type svcDescriptorish interface {
76 descriptorish
77 GetServiceOptions() *dpb.ServiceOptions
78 GetMethods() []methodDescriptorish
79}
80
81type methodDescriptorish interface {
82 descriptorish
83 GetMethodOptions() *dpb.MethodOptions
84}
85
86// The hierarchy of descriptorish implementations backed by
87// rich descriptors:
88
89type richFileDescriptorish struct {
90 *desc.FileDescriptor
91}
92
93func (d richFileDescriptorish) GetFile() fileDescriptorish {
94 return d
95}
96
97func (d richFileDescriptorish) GetPublicDependencies() []fileDescriptorish {
98 deps := d.FileDescriptor.GetPublicDependencies()
99 ret := make([]fileDescriptorish, len(deps))
100 for i, d := range deps {
101 ret[i] = richFileDescriptorish{FileDescriptor: d}
102 }
103 return ret
104}
105
106func (d richFileDescriptorish) GetDependencies() []fileDescriptorish {
107 deps := d.FileDescriptor.GetDependencies()
108 ret := make([]fileDescriptorish, len(deps))
109 for i, d := range deps {
110 ret[i] = richFileDescriptorish{FileDescriptor: d}
111 }
112 return ret
113}
114
115func (d richFileDescriptorish) GetMessageTypes() []msgDescriptorish {
116 msgs := d.FileDescriptor.GetMessageTypes()
117 ret := make([]msgDescriptorish, len(msgs))
118 for i, m := range msgs {
119 ret[i] = richMsgDescriptorish{MessageDescriptor: m}
120 }
121 return ret
122}
123
124func (d richFileDescriptorish) GetExtensions() []fldDescriptorish {
125 flds := d.FileDescriptor.GetExtensions()
126 ret := make([]fldDescriptorish, len(flds))
127 for i, f := range flds {
128 ret[i] = richFldDescriptorish{FieldDescriptor: f}
129 }
130 return ret
131}
132
133func (d richFileDescriptorish) GetEnumTypes() []enumDescriptorish {
134 ens := d.FileDescriptor.GetEnumTypes()
135 ret := make([]enumDescriptorish, len(ens))
136 for i, en := range ens {
137 ret[i] = richEnumDescriptorish{EnumDescriptor: en}
138 }
139 return ret
140}
141
142func (d richFileDescriptorish) GetServices() []svcDescriptorish {
143 svcs := d.FileDescriptor.GetServices()
144 ret := make([]svcDescriptorish, len(svcs))
145 for i, s := range svcs {
146 ret[i] = richSvcDescriptorish{ServiceDescriptor: s}
147 }
148 return ret
149}
150
151type richMsgDescriptorish struct {
152 *desc.MessageDescriptor
153}
154
155func (d richMsgDescriptorish) GetFile() fileDescriptorish {
156 return richFileDescriptorish{FileDescriptor: d.MessageDescriptor.GetFile()}
157}
158
159func (d richMsgDescriptorish) GetFields() []fldDescriptorish {
160 flds := d.MessageDescriptor.GetFields()
161 ret := make([]fldDescriptorish, len(flds))
162 for i, f := range flds {
163 ret[i] = richFldDescriptorish{FieldDescriptor: f}
164 }
165 return ret
166}
167
168func (d richMsgDescriptorish) GetOneOfs() []oneofDescriptorish {
169 oos := d.MessageDescriptor.GetOneOfs()
170 ret := make([]oneofDescriptorish, len(oos))
171 for i, oo := range oos {
172 ret[i] = richOneOfDescriptorish{OneOfDescriptor: oo}
173 }
174 return ret
175}
176
177func (d richMsgDescriptorish) GetExtensionRanges() []extRangeDescriptorish {
178 md := d.MessageDescriptor
179 mdFqn := md.GetFullyQualifiedName()
180 extrs := md.AsDescriptorProto().GetExtensionRange()
181 ret := make([]extRangeDescriptorish, len(extrs))
182 for i, extr := range extrs {
183 ret[i] = extRangeDescriptorish{
184 er: extr,
185 qual: mdFqn,
186 file: richFileDescriptorish{FileDescriptor: md.GetFile()},
187 }
188 }
189 return ret
190}
191
192func (d richMsgDescriptorish) GetNestedMessageTypes() []msgDescriptorish {
193 msgs := d.MessageDescriptor.GetNestedMessageTypes()
194 ret := make([]msgDescriptorish, len(msgs))
195 for i, m := range msgs {
196 ret[i] = richMsgDescriptorish{MessageDescriptor: m}
197 }
198 return ret
199}
200
201func (d richMsgDescriptorish) GetNestedExtensions() []fldDescriptorish {
202 flds := d.MessageDescriptor.GetNestedExtensions()
203 ret := make([]fldDescriptorish, len(flds))
204 for i, f := range flds {
205 ret[i] = richFldDescriptorish{FieldDescriptor: f}
206 }
207 return ret
208}
209
210func (d richMsgDescriptorish) GetNestedEnumTypes() []enumDescriptorish {
211 ens := d.MessageDescriptor.GetNestedEnumTypes()
212 ret := make([]enumDescriptorish, len(ens))
213 for i, en := range ens {
214 ret[i] = richEnumDescriptorish{EnumDescriptor: en}
215 }
216 return ret
217}
218
219type richFldDescriptorish struct {
220 *desc.FieldDescriptor
221}
222
223func (d richFldDescriptorish) GetFile() fileDescriptorish {
224 return richFileDescriptorish{FileDescriptor: d.FieldDescriptor.GetFile()}
225}
226
227func (d richFldDescriptorish) AsFieldDescriptorProto() *dpb.FieldDescriptorProto {
228 return d.FieldDescriptor.AsFieldDescriptorProto()
229}
230
231type richOneOfDescriptorish struct {
232 *desc.OneOfDescriptor
233}
234
235func (d richOneOfDescriptorish) GetFile() fileDescriptorish {
236 return richFileDescriptorish{FileDescriptor: d.OneOfDescriptor.GetFile()}
237}
238
239type richEnumDescriptorish struct {
240 *desc.EnumDescriptor
241}
242
243func (d richEnumDescriptorish) GetFile() fileDescriptorish {
244 return richFileDescriptorish{FileDescriptor: d.EnumDescriptor.GetFile()}
245}
246
247func (d richEnumDescriptorish) GetValues() []enumValDescriptorish {
248 vals := d.EnumDescriptor.GetValues()
249 ret := make([]enumValDescriptorish, len(vals))
250 for i, val := range vals {
251 ret[i] = richEnumValDescriptorish{EnumValueDescriptor: val}
252 }
253 return ret
254}
255
256type richEnumValDescriptorish struct {
257 *desc.EnumValueDescriptor
258}
259
260func (d richEnumValDescriptorish) GetFile() fileDescriptorish {
261 return richFileDescriptorish{FileDescriptor: d.EnumValueDescriptor.GetFile()}
262}
263
264type richSvcDescriptorish struct {
265 *desc.ServiceDescriptor
266}
267
268func (d richSvcDescriptorish) GetFile() fileDescriptorish {
269 return richFileDescriptorish{FileDescriptor: d.ServiceDescriptor.GetFile()}
270}
271
272func (d richSvcDescriptorish) GetMethods() []methodDescriptorish {
273 mtds := d.ServiceDescriptor.GetMethods()
274 ret := make([]methodDescriptorish, len(mtds))
275 for i, mtd := range mtds {
276 ret[i] = richMethodDescriptorish{MethodDescriptor: mtd}
277 }
278 return ret
279}
280
281type richMethodDescriptorish struct {
282 *desc.MethodDescriptor
283}
284
285func (d richMethodDescriptorish) GetFile() fileDescriptorish {
286 return richFileDescriptorish{FileDescriptor: d.MethodDescriptor.GetFile()}
287}
288
289// The hierarchy of descriptorish implementations backed by
290// plain descriptor protos:
291
292type poorFileDescriptorish struct {
293 *dpb.FileDescriptorProto
294}
295
296func (d poorFileDescriptorish) GetFile() fileDescriptorish {
297 return d
298}
299
300func (d poorFileDescriptorish) GetFullyQualifiedName() string {
301 return d.FileDescriptorProto.GetName()
302}
303
304func (d poorFileDescriptorish) AsProto() proto.Message {
305 return d.FileDescriptorProto
306}
307
308func (d poorFileDescriptorish) GetFileOptions() *dpb.FileOptions {
309 return d.FileDescriptorProto.GetOptions()
310}
311
312func (d poorFileDescriptorish) FindSymbol(name string) desc.Descriptor {
313 return nil
314}
315
316func (d poorFileDescriptorish) GetPublicDependencies() []fileDescriptorish {
317 return nil
318}
319
320func (d poorFileDescriptorish) GetDependencies() []fileDescriptorish {
321 return nil
322}
323
324func (d poorFileDescriptorish) GetMessageTypes() []msgDescriptorish {
325 msgs := d.FileDescriptorProto.GetMessageType()
326 pkg := d.FileDescriptorProto.GetPackage()
327 ret := make([]msgDescriptorish, len(msgs))
328 for i, m := range msgs {
329 ret[i] = poorMsgDescriptorish{
330 DescriptorProto: m,
331 qual: pkg,
332 file: d,
333 }
334 }
335 return ret
336}
337
338func (d poorFileDescriptorish) GetExtensions() []fldDescriptorish {
339 exts := d.FileDescriptorProto.GetExtension()
340 pkg := d.FileDescriptorProto.GetPackage()
341 ret := make([]fldDescriptorish, len(exts))
342 for i, e := range exts {
343 ret[i] = poorFldDescriptorish{
344 FieldDescriptorProto: e,
345 qual: pkg,
346 file: d,
347 }
348 }
349 return ret
350}
351
352func (d poorFileDescriptorish) GetEnumTypes() []enumDescriptorish {
353 ens := d.FileDescriptorProto.GetEnumType()
354 pkg := d.FileDescriptorProto.GetPackage()
355 ret := make([]enumDescriptorish, len(ens))
356 for i, e := range ens {
357 ret[i] = poorEnumDescriptorish{
358 EnumDescriptorProto: e,
359 qual: pkg,
360 file: d,
361 }
362 }
363 return ret
364}
365
366func (d poorFileDescriptorish) GetServices() []svcDescriptorish {
367 svcs := d.FileDescriptorProto.GetService()
368 pkg := d.FileDescriptorProto.GetPackage()
369 ret := make([]svcDescriptorish, len(svcs))
370 for i, s := range svcs {
371 ret[i] = poorSvcDescriptorish{
372 ServiceDescriptorProto: s,
373 qual: pkg,
374 file: d,
375 }
376 }
377 return ret
378}
379
380type poorMsgDescriptorish struct {
381 *dpb.DescriptorProto
382 qual string
383 file fileDescriptorish
384}
385
386func (d poorMsgDescriptorish) GetFile() fileDescriptorish {
387 return d.file
388}
389
390func (d poorMsgDescriptorish) GetFullyQualifiedName() string {
391 return qualify(d.qual, d.DescriptorProto.GetName())
392}
393
394func qualify(qual, name string) string {
395 if qual == "" {
396 return name
397 } else {
398 return fmt.Sprintf("%s.%s", qual, name)
399 }
400}
401
402func (d poorMsgDescriptorish) AsProto() proto.Message {
403 return d.DescriptorProto
404}
405
406func (d poorMsgDescriptorish) GetMessageOptions() *dpb.MessageOptions {
407 return d.DescriptorProto.GetOptions()
408}
409
410func (d poorMsgDescriptorish) GetFields() []fldDescriptorish {
411 flds := d.DescriptorProto.GetField()
412 ret := make([]fldDescriptorish, len(flds))
413 for i, f := range flds {
414 ret[i] = poorFldDescriptorish{
415 FieldDescriptorProto: f,
416 qual: d.GetFullyQualifiedName(),
417 file: d.file,
418 }
419 }
420 return ret
421}
422
423func (d poorMsgDescriptorish) GetOneOfs() []oneofDescriptorish {
424 oos := d.DescriptorProto.GetOneofDecl()
425 ret := make([]oneofDescriptorish, len(oos))
426 for i, oo := range oos {
427 ret[i] = poorOneOfDescriptorish{
428 OneofDescriptorProto: oo,
429 qual: d.GetFullyQualifiedName(),
430 file: d.file,
431 }
432 }
433 return ret
434}
435
436func (d poorMsgDescriptorish) GetExtensionRanges() []extRangeDescriptorish {
437 mdFqn := d.GetFullyQualifiedName()
438 extrs := d.DescriptorProto.GetExtensionRange()
439 ret := make([]extRangeDescriptorish, len(extrs))
440 for i, extr := range extrs {
441 ret[i] = extRangeDescriptorish{
442 er: extr,
443 qual: mdFqn,
444 file: d.file,
445 }
446 }
447 return ret
448}
449
450func (d poorMsgDescriptorish) GetNestedMessageTypes() []msgDescriptorish {
451 msgs := d.DescriptorProto.GetNestedType()
452 ret := make([]msgDescriptorish, len(msgs))
453 for i, m := range msgs {
454 ret[i] = poorMsgDescriptorish{
455 DescriptorProto: m,
456 qual: d.GetFullyQualifiedName(),
457 file: d.file,
458 }
459 }
460 return ret
461}
462
463func (d poorMsgDescriptorish) GetNestedExtensions() []fldDescriptorish {
464 flds := d.DescriptorProto.GetExtension()
465 ret := make([]fldDescriptorish, len(flds))
466 for i, f := range flds {
467 ret[i] = poorFldDescriptorish{
468 FieldDescriptorProto: f,
469 qual: d.GetFullyQualifiedName(),
470 file: d.file,
471 }
472 }
473 return ret
474}
475
476func (d poorMsgDescriptorish) GetNestedEnumTypes() []enumDescriptorish {
477 ens := d.DescriptorProto.GetEnumType()
478 ret := make([]enumDescriptorish, len(ens))
479 for i, en := range ens {
480 ret[i] = poorEnumDescriptorish{
481 EnumDescriptorProto: en,
482 qual: d.GetFullyQualifiedName(),
483 file: d.file,
484 }
485 }
486 return ret
487}
488
489type poorFldDescriptorish struct {
490 *dpb.FieldDescriptorProto
491 qual string
492 file fileDescriptorish
493}
494
495func (d poorFldDescriptorish) GetFile() fileDescriptorish {
496 return d.file
497}
498
499func (d poorFldDescriptorish) GetFullyQualifiedName() string {
500 return qualify(d.qual, d.FieldDescriptorProto.GetName())
501}
502
503func (d poorFldDescriptorish) AsProto() proto.Message {
504 return d.FieldDescriptorProto
505}
506
507func (d poorFldDescriptorish) GetFieldOptions() *dpb.FieldOptions {
508 return d.FieldDescriptorProto.GetOptions()
509}
510
511func (d poorFldDescriptorish) GetMessageType() *desc.MessageDescriptor {
512 return nil
513}
514
515func (d poorFldDescriptorish) GetEnumType() *desc.EnumDescriptor {
516 return nil
517}
518
519type poorOneOfDescriptorish struct {
520 *dpb.OneofDescriptorProto
521 qual string
522 file fileDescriptorish
523}
524
525func (d poorOneOfDescriptorish) GetFile() fileDescriptorish {
526 return d.file
527}
528
529func (d poorOneOfDescriptorish) GetFullyQualifiedName() string {
530 return qualify(d.qual, d.OneofDescriptorProto.GetName())
531}
532
533func (d poorOneOfDescriptorish) AsProto() proto.Message {
534 return d.OneofDescriptorProto
535}
536
537func (d poorOneOfDescriptorish) GetOneOfOptions() *dpb.OneofOptions {
538 return d.OneofDescriptorProto.GetOptions()
539}
540
541func (d poorFldDescriptorish) AsFieldDescriptorProto() *dpb.FieldDescriptorProto {
542 return d.FieldDescriptorProto
543}
544
545type poorEnumDescriptorish struct {
546 *dpb.EnumDescriptorProto
547 qual string
548 file fileDescriptorish
549}
550
551func (d poorEnumDescriptorish) GetFile() fileDescriptorish {
552 return d.file
553}
554
555func (d poorEnumDescriptorish) GetFullyQualifiedName() string {
556 return qualify(d.qual, d.EnumDescriptorProto.GetName())
557}
558
559func (d poorEnumDescriptorish) AsProto() proto.Message {
560 return d.EnumDescriptorProto
561}
562
563func (d poorEnumDescriptorish) GetEnumOptions() *dpb.EnumOptions {
564 return d.EnumDescriptorProto.GetOptions()
565}
566
567func (d poorEnumDescriptorish) GetValues() []enumValDescriptorish {
568 vals := d.EnumDescriptorProto.GetValue()
569 ret := make([]enumValDescriptorish, len(vals))
570 for i, v := range vals {
571 ret[i] = poorEnumValDescriptorish{
572 EnumValueDescriptorProto: v,
573 qual: d.GetFullyQualifiedName(),
574 file: d.file,
575 }
576 }
577 return ret
578}
579
580type poorEnumValDescriptorish struct {
581 *dpb.EnumValueDescriptorProto
582 qual string
583 file fileDescriptorish
584}
585
586func (d poorEnumValDescriptorish) GetFile() fileDescriptorish {
587 return d.file
588}
589
590func (d poorEnumValDescriptorish) GetFullyQualifiedName() string {
591 return qualify(d.qual, d.EnumValueDescriptorProto.GetName())
592}
593
594func (d poorEnumValDescriptorish) AsProto() proto.Message {
595 return d.EnumValueDescriptorProto
596}
597
598func (d poorEnumValDescriptorish) GetEnumValueOptions() *dpb.EnumValueOptions {
599 return d.EnumValueDescriptorProto.GetOptions()
600}
601
602type poorSvcDescriptorish struct {
603 *dpb.ServiceDescriptorProto
604 qual string
605 file fileDescriptorish
606}
607
608func (d poorSvcDescriptorish) GetFile() fileDescriptorish {
609 return d.file
610}
611
612func (d poorSvcDescriptorish) GetFullyQualifiedName() string {
613 return qualify(d.qual, d.ServiceDescriptorProto.GetName())
614}
615
616func (d poorSvcDescriptorish) AsProto() proto.Message {
617 return d.ServiceDescriptorProto
618}
619
620func (d poorSvcDescriptorish) GetServiceOptions() *dpb.ServiceOptions {
621 return d.ServiceDescriptorProto.GetOptions()
622}
623
624func (d poorSvcDescriptorish) GetMethods() []methodDescriptorish {
625 mtds := d.ServiceDescriptorProto.GetMethod()
626 ret := make([]methodDescriptorish, len(mtds))
627 for i, m := range mtds {
628 ret[i] = poorMethodDescriptorish{
629 MethodDescriptorProto: m,
630 qual: d.GetFullyQualifiedName(),
631 file: d.file,
632 }
633 }
634 return ret
635}
636
637type poorMethodDescriptorish struct {
638 *dpb.MethodDescriptorProto
639 qual string
640 file fileDescriptorish
641}
642
643func (d poorMethodDescriptorish) GetFile() fileDescriptorish {
644 return d.file
645}
646
647func (d poorMethodDescriptorish) GetFullyQualifiedName() string {
648 return qualify(d.qual, d.MethodDescriptorProto.GetName())
649}
650
651func (d poorMethodDescriptorish) AsProto() proto.Message {
652 return d.MethodDescriptorProto
653}
654
655func (d poorMethodDescriptorish) GetMethodOptions() *dpb.MethodOptions {
656 return d.MethodDescriptorProto.GetOptions()
657}
658
659type extRangeDescriptorish struct {
660 er *dpb.DescriptorProto_ExtensionRange
661 qual string
662 file fileDescriptorish
663}
664
665func (er extRangeDescriptorish) GetFile() fileDescriptorish {
666 return er.file
667}
668
669func (er extRangeDescriptorish) GetFullyQualifiedName() string {
670 return qualify(er.qual, fmt.Sprintf("%d-%d", er.er.GetStart(), er.er.GetEnd()-1))
671}
672
673func (er extRangeDescriptorish) AsProto() proto.Message {
674 return er.er
675}
676
677func (er extRangeDescriptorish) GetExtensionRangeOptions() *dpb.ExtensionRangeOptions {
678 return er.er.GetOptions()
679}
680
681func interpretFileOptions(r *parseResult, fd fileDescriptorish) error {
682 opts := fd.GetFileOptions()
683 if opts != nil {
684 if len(opts.UninterpretedOption) > 0 {
685 if remain, err := interpretOptions(r, fd, opts, opts.UninterpretedOption); err != nil {
686 return err
687 } else {
688 opts.UninterpretedOption = remain
689 }
690 }
691 }
692 for _, md := range fd.GetMessageTypes() {
693 if err := interpretMessageOptions(r, md); err != nil {
694 return err
695 }
696 }
697 for _, fld := range fd.GetExtensions() {
698 if err := interpretFieldOptions(r, fld); err != nil {
699 return err
700 }
701 }
702 for _, ed := range fd.GetEnumTypes() {
703 if err := interpretEnumOptions(r, ed); err != nil {
704 return err
705 }
706 }
707 for _, sd := range fd.GetServices() {
708 opts := sd.GetServiceOptions()
709 if opts != nil {
710 if len(opts.UninterpretedOption) > 0 {
711 if remain, err := interpretOptions(r, sd, opts, opts.UninterpretedOption); err != nil {
712 return err
713 } else {
714 opts.UninterpretedOption = remain
715 }
716 }
717 }
718 for _, mtd := range sd.GetMethods() {
719 opts := mtd.GetMethodOptions()
720 if opts != nil {
721 if len(opts.UninterpretedOption) > 0 {
722 if remain, err := interpretOptions(r, mtd, opts, opts.UninterpretedOption); err != nil {
723 return err
724 } else {
725 opts.UninterpretedOption = remain
726 }
727 }
728 }
729 }
730 }
731 return nil
732}
733
734func interpretMessageOptions(r *parseResult, md msgDescriptorish) error {
735 opts := md.GetMessageOptions()
736 if opts != nil {
737 if len(opts.UninterpretedOption) > 0 {
738 if remain, err := interpretOptions(r, md, opts, opts.UninterpretedOption); err != nil {
739 return err
740 } else {
741 opts.UninterpretedOption = remain
742 }
743 }
744 }
745 for _, fld := range md.GetFields() {
746 if err := interpretFieldOptions(r, fld); err != nil {
747 return err
748 }
749 }
750 for _, ood := range md.GetOneOfs() {
751 opts := ood.GetOneOfOptions()
752 if opts != nil {
753 if len(opts.UninterpretedOption) > 0 {
754 if remain, err := interpretOptions(r, ood, opts, opts.UninterpretedOption); err != nil {
755 return err
756 } else {
757 opts.UninterpretedOption = remain
758 }
759 }
760 }
761 }
762 for _, fld := range md.GetNestedExtensions() {
763 if err := interpretFieldOptions(r, fld); err != nil {
764 return err
765 }
766 }
767 for _, er := range md.GetExtensionRanges() {
768 opts := er.GetExtensionRangeOptions()
769 if opts != nil {
770 if len(opts.UninterpretedOption) > 0 {
771 if remain, err := interpretOptions(r, er, opts, opts.UninterpretedOption); err != nil {
772 return err
773 } else {
774 opts.UninterpretedOption = remain
775 }
776 }
777 }
778 }
779 for _, nmd := range md.GetNestedMessageTypes() {
780 if err := interpretMessageOptions(r, nmd); err != nil {
781 return err
782 }
783 }
784 for _, ed := range md.GetNestedEnumTypes() {
785 if err := interpretEnumOptions(r, ed); err != nil {
786 return err
787 }
788 }
789 return nil
790}
791
792func interpretFieldOptions(r *parseResult, fld fldDescriptorish) error {
793 opts := fld.GetFieldOptions()
794 if opts != nil {
795 if len(opts.UninterpretedOption) > 0 {
796 uo := opts.UninterpretedOption
797 scope := fmt.Sprintf("field %s", fld.GetFullyQualifiedName())
798
799 // process json_name pseudo-option
800 if index, err := findOption(r, scope, uo, "json_name"); err != nil && !r.lenient {
801 return err
802 } else if err == nil && index >= 0 {
803 opt := uo[index]
804 optNode := r.getOptionNode(opt)
805
806 // attribute source code info
807 if on, ok := optNode.(*optionNode); ok {
808 r.interpretedOptions[on] = []int32{-1, internal.Field_jsonNameTag}
809 }
810 uo = removeOption(uo, index)
811 if opt.StringValue == nil {
812 return ErrorWithSourcePos{Pos: optNode.getValue().start(), Underlying: fmt.Errorf("%s: expecting string value for json_name option", scope)}
813 }
814 fld.AsFieldDescriptorProto().JsonName = proto.String(string(opt.StringValue))
815 }
816
817 // and process default pseudo-option
818 if index, err := processDefaultOption(r, scope, fld, uo); err != nil && !r.lenient {
819 return err
820 } else if err == nil && index >= 0 {
821 // attribute source code info
822 optNode := r.getOptionNode(uo[index])
823 if on, ok := optNode.(*optionNode); ok {
824 r.interpretedOptions[on] = []int32{-1, internal.Field_defaultTag}
825 }
826 uo = removeOption(uo, index)
827 }
828
829 if len(uo) == 0 {
830 // no real options, only pseudo-options above? clear out options
831 fld.AsFieldDescriptorProto().Options = nil
832 } else if remain, err := interpretOptions(r, fld, opts, uo); err != nil {
833 return err
834 } else {
835 opts.UninterpretedOption = remain
836 }
837 }
838 }
839 return nil
840}
841
842func processDefaultOption(res *parseResult, scope string, fld fldDescriptorish, uos []*dpb.UninterpretedOption) (defaultIndex int, err error) {
843 found, err := findOption(res, scope, uos, "default")
844 if err != nil {
845 return -1, err
846 } else if found == -1 {
847 return -1, nil
848 }
849 opt := uos[found]
850 optNode := res.getOptionNode(opt)
851 fdp := fld.AsFieldDescriptorProto()
852 if fdp.GetLabel() == dpb.FieldDescriptorProto_LABEL_REPEATED {
853 return -1, ErrorWithSourcePos{Pos: optNode.getName().start(), Underlying: fmt.Errorf("%s: default value cannot be set because field is repeated", scope)}
854 }
855 if fdp.GetType() == dpb.FieldDescriptorProto_TYPE_GROUP || fdp.GetType() == dpb.FieldDescriptorProto_TYPE_MESSAGE {
856 return -1, ErrorWithSourcePos{Pos: optNode.getName().start(), Underlying: fmt.Errorf("%s: default value cannot be set because field is a message", scope)}
857 }
858 val := optNode.getValue()
859 if _, ok := val.(*aggregateLiteralNode); ok {
860 return -1, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%s: default value cannot be an aggregate", scope)}
861 }
862 mc := &messageContext{
863 res: res,
864 file: fld.GetFile(),
865 elementName: fld.GetFullyQualifiedName(),
866 elementType: descriptorType(fld.AsProto()),
867 option: opt,
868 }
869 v, err := fieldValue(res, mc, fld, val, true)
870 if err != nil {
871 return -1, err
872 }
873 if str, ok := v.(string); ok {
874 fld.AsFieldDescriptorProto().DefaultValue = proto.String(str)
875 } else if b, ok := v.([]byte); ok {
876 fld.AsFieldDescriptorProto().DefaultValue = proto.String(encodeDefaultBytes(b))
877 } else {
878 var flt float64
879 var ok bool
880 if flt, ok = v.(float64); !ok {
881 var flt32 float32
882 if flt32, ok = v.(float32); ok {
883 flt = float64(flt32)
884 }
885 }
886 if ok {
887 if math.IsInf(flt, 1) {
888 fld.AsFieldDescriptorProto().DefaultValue = proto.String("inf")
889 } else if ok && math.IsInf(flt, -1) {
890 fld.AsFieldDescriptorProto().DefaultValue = proto.String("-inf")
891 } else if ok && math.IsNaN(flt) {
892 fld.AsFieldDescriptorProto().DefaultValue = proto.String("nan")
893 } else {
894 fld.AsFieldDescriptorProto().DefaultValue = proto.String(fmt.Sprintf("%v", v))
895 }
896 } else {
897 fld.AsFieldDescriptorProto().DefaultValue = proto.String(fmt.Sprintf("%v", v))
898 }
899 }
900 return found, nil
901}
902
903func encodeDefaultBytes(b []byte) string {
904 var buf bytes.Buffer
905 writeEscapedBytes(&buf, b)
906 return buf.String()
907}
908
909func interpretEnumOptions(r *parseResult, ed enumDescriptorish) error {
910 opts := ed.GetEnumOptions()
911 if opts != nil {
912 if len(opts.UninterpretedOption) > 0 {
913 if remain, err := interpretOptions(r, ed, opts, opts.UninterpretedOption); err != nil {
914 return err
915 } else {
916 opts.UninterpretedOption = remain
917 }
918 }
919 }
920 for _, evd := range ed.GetValues() {
921 opts := evd.GetEnumValueOptions()
922 if opts != nil {
923 if len(opts.UninterpretedOption) > 0 {
924 if remain, err := interpretOptions(r, evd, opts, opts.UninterpretedOption); err != nil {
925 return err
926 } else {
927 opts.UninterpretedOption = remain
928 }
929 }
930 }
931 }
932 return nil
933}
934
935func interpretOptions(res *parseResult, element descriptorish, opts proto.Message, uninterpreted []*dpb.UninterpretedOption) ([]*dpb.UninterpretedOption, error) {
936 optsd, err := desc.LoadMessageDescriptorForMessage(opts)
937 if err != nil {
938 if res.lenient {
939 return uninterpreted, nil
940 }
941 return nil, err
942 }
943 dm := dynamic.NewMessage(optsd)
944 err = dm.ConvertFrom(opts)
945 if err != nil {
946 if res.lenient {
947 return uninterpreted, nil
948 }
949 node := res.nodes[element.AsProto()]
950 return nil, ErrorWithSourcePos{Pos: node.start(), Underlying: err}
951 }
952
953 mc := &messageContext{res: res, file: element.GetFile(), elementName: element.GetFullyQualifiedName(), elementType: descriptorType(element.AsProto())}
954 var remain []*dpb.UninterpretedOption
955 for _, uo := range uninterpreted {
956 node := res.getOptionNode(uo)
957 if !uo.Name[0].GetIsExtension() && uo.Name[0].GetNamePart() == "uninterpreted_option" {
958 if res.lenient {
959 remain = append(remain, uo)
960 continue
961 }
962 // uninterpreted_option might be found reflectively, but is not actually valid for use
963 return nil, ErrorWithSourcePos{Pos: node.getName().start(), Underlying: fmt.Errorf("%vinvalid option 'uninterpreted_option'", mc)}
964 }
965 mc.option = uo
966 path, err := interpretField(res, mc, element, dm, uo, 0, nil)
967 if err != nil {
968 if res.lenient {
969 remain = append(remain, uo)
970 continue
971 }
972 return nil, err
973 }
974 if optn, ok := node.(*optionNode); ok {
975 res.interpretedOptions[optn] = path
976 }
977 }
978
979 if err := dm.ValidateRecursive(); err != nil {
980 // if lenient, we'll let this pass, but it means that some required field was not set!
981 // TODO: do this in a more granular way, so we can validate individual fields
982 // and leave them uninterpreted, instead of just having to live with the
983 // thing having invalid data in extensions.
984 if !res.lenient {
985 node := res.nodes[element.AsProto()]
986 return nil, ErrorWithSourcePos{Pos: node.start(), Underlying: fmt.Errorf("error in %s options: %v", descriptorType(element.AsProto()), err)}
987 }
988 }
989
990 if res.lenient {
991 // If we're lenient, then we don't want to clobber the passed in message
992 // and leave it partially populated. So we convert into a copy first
993 optsClone := proto.Clone(opts)
994 if err := dm.ConvertTo(optsClone); err != nil {
995 // TODO: do this in a more granular way, so we can convert individual
996 // fields and leave bad ones uninterpreted instead of skipping all of
997 // the work we've done so far.
998 return uninterpreted, nil
999 }
1000 // conversion from dynamic message above worked, so now
1001 // it is safe to overwrite the passed in message
1002 opts.Reset()
1003 proto.Merge(opts, optsClone)
1004
1005 } else {
1006 // not lenient: try to convert into the passed in message
Scott Baker4a35a702019-11-26 08:17:33 -08001007 // and fail if not successful
Zack Williamse940c7a2019-08-21 14:25:39 -07001008 if err := dm.ConvertTo(opts); err != nil {
1009 node := res.nodes[element.AsProto()]
1010 return nil, ErrorWithSourcePos{Pos: node.start(), Underlying: err}
1011 }
1012 }
1013
1014 return remain, nil
1015}
1016
1017func interpretField(res *parseResult, mc *messageContext, element descriptorish, dm *dynamic.Message, opt *dpb.UninterpretedOption, nameIndex int, pathPrefix []int32) (path []int32, err error) {
1018 var fld *desc.FieldDescriptor
1019 nm := opt.GetName()[nameIndex]
1020 node := res.getOptionNamePartNode(nm)
1021 if nm.GetIsExtension() {
1022 extName := nm.GetNamePart()
1023 if extName[0] == '.' {
1024 extName = extName[1:] /* skip leading dot */
1025 }
1026 fld = findExtension(element.GetFile(), extName, false, map[fileDescriptorish]struct{}{})
1027 if fld == nil {
1028 return nil, ErrorWithSourcePos{
1029 Pos: node.start(),
1030 Underlying: fmt.Errorf("%vunrecognized extension %s of %s",
1031 mc, extName, dm.GetMessageDescriptor().GetFullyQualifiedName()),
1032 }
1033 }
1034 if fld.GetOwner().GetFullyQualifiedName() != dm.GetMessageDescriptor().GetFullyQualifiedName() {
1035 return nil, ErrorWithSourcePos{
1036 Pos: node.start(),
1037 Underlying: fmt.Errorf("%vextension %s should extend %s but instead extends %s",
1038 mc, extName, dm.GetMessageDescriptor().GetFullyQualifiedName(), fld.GetOwner().GetFullyQualifiedName()),
1039 }
1040 }
1041 } else {
1042 fld = dm.GetMessageDescriptor().FindFieldByName(nm.GetNamePart())
1043 if fld == nil {
1044 return nil, ErrorWithSourcePos{
1045 Pos: node.start(),
1046 Underlying: fmt.Errorf("%vfield %s of %s does not exist",
1047 mc, nm.GetNamePart(), dm.GetMessageDescriptor().GetFullyQualifiedName()),
1048 }
1049 }
1050 }
1051
1052 path = append(pathPrefix, fld.GetNumber())
1053
1054 if len(opt.GetName()) > nameIndex+1 {
1055 nextnm := opt.GetName()[nameIndex+1]
1056 nextnode := res.getOptionNamePartNode(nextnm)
1057 if fld.GetType() != dpb.FieldDescriptorProto_TYPE_MESSAGE {
1058 return nil, ErrorWithSourcePos{
1059 Pos: nextnode.start(),
1060 Underlying: fmt.Errorf("%vcannot set field %s because %s is not a message",
1061 mc, nextnm.GetNamePart(), nm.GetNamePart()),
1062 }
1063 }
1064 if fld.IsRepeated() {
1065 return nil, ErrorWithSourcePos{
1066 Pos: nextnode.start(),
1067 Underlying: fmt.Errorf("%vcannot set field %s because %s is repeated (must use an aggregate)",
1068 mc, nextnm.GetNamePart(), nm.GetNamePart()),
1069 }
1070 }
1071 var fdm *dynamic.Message
1072 var err error
1073 if dm.HasField(fld) {
1074 var v interface{}
1075 v, err = dm.TryGetField(fld)
1076 fdm, _ = v.(*dynamic.Message)
1077 } else {
1078 fdm = dynamic.NewMessage(fld.GetMessageType())
1079 err = dm.TrySetField(fld, fdm)
1080 }
1081 if err != nil {
1082 return nil, ErrorWithSourcePos{Pos: node.start(), Underlying: err}
1083 }
1084 // recurse to set next part of name
1085 return interpretField(res, mc, element, fdm, opt, nameIndex+1, path)
1086 }
1087
1088 optNode := res.getOptionNode(opt)
1089 if err := setOptionField(res, mc, dm, fld, node, optNode.getValue()); err != nil {
1090 return nil, err
1091 }
1092 if fld.IsRepeated() {
1093 path = append(path, int32(dm.FieldLength(fld))-1)
1094 }
1095 return path, nil
1096}
1097
1098func findExtension(fd fileDescriptorish, name string, public bool, checked map[fileDescriptorish]struct{}) *desc.FieldDescriptor {
1099 if _, ok := checked[fd]; ok {
1100 return nil
1101 }
1102 checked[fd] = struct{}{}
1103 d := fd.FindSymbol(name)
1104 if d != nil {
1105 if fld, ok := d.(*desc.FieldDescriptor); ok {
1106 return fld
1107 }
1108 return nil
1109 }
1110
1111 // When public = false, we are searching only directly imported symbols. But we
1112 // also need to search transitive public imports due to semantics of public imports.
1113 if public {
1114 for _, dep := range fd.GetPublicDependencies() {
1115 d := findExtension(dep, name, true, checked)
1116 if d != nil {
1117 return d
1118 }
1119 }
1120 } else {
1121 for _, dep := range fd.GetDependencies() {
1122 d := findExtension(dep, name, true, checked)
1123 if d != nil {
1124 return d
1125 }
1126 }
1127 }
1128 return nil
1129}
1130
1131func setOptionField(res *parseResult, mc *messageContext, dm *dynamic.Message, fld *desc.FieldDescriptor, name node, val valueNode) error {
1132 v := val.value()
1133 if sl, ok := v.([]valueNode); ok {
1134 // handle slices a little differently than the others
1135 if !fld.IsRepeated() {
1136 return ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vvalue is an array but field is not repeated", mc)}
1137 }
1138 origPath := mc.optAggPath
1139 defer func() {
1140 mc.optAggPath = origPath
1141 }()
1142 for index, item := range sl {
1143 mc.optAggPath = fmt.Sprintf("%s[%d]", origPath, index)
1144 if v, err := fieldValue(res, mc, richFldDescriptorish{FieldDescriptor: fld}, item, false); err != nil {
1145 return err
1146 } else if err = dm.TryAddRepeatedField(fld, v); err != nil {
1147 return ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%verror setting value: %s", mc, err)}
1148 }
1149 }
1150 return nil
1151 }
1152
1153 v, err := fieldValue(res, mc, richFldDescriptorish{FieldDescriptor: fld}, val, false)
1154 if err != nil {
1155 return err
1156 }
1157 if fld.IsRepeated() {
1158 err = dm.TryAddRepeatedField(fld, v)
1159 } else {
1160 if dm.HasField(fld) {
1161 return ErrorWithSourcePos{Pos: name.start(), Underlying: fmt.Errorf("%vnon-repeated option field %s already set", mc, fieldName(fld))}
1162 }
1163 err = dm.TrySetField(fld, v)
1164 }
1165 if err != nil {
1166 return ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%verror setting value: %s", mc, err)}
1167 }
1168
1169 return nil
1170}
1171
1172type messageContext struct {
1173 res *parseResult
1174 file fileDescriptorish
1175 elementType string
1176 elementName string
1177 option *dpb.UninterpretedOption
1178 optAggPath string
1179}
1180
1181func (c *messageContext) String() string {
1182 var ctx bytes.Buffer
1183 if c.elementType != "file" {
1184 fmt.Fprintf(&ctx, "%s %s: ", c.elementType, c.elementName)
1185 }
1186 if c.option != nil && c.option.Name != nil {
1187 ctx.WriteString("option ")
1188 writeOptionName(&ctx, c.option.Name)
1189 if c.res.nodes == nil {
1190 // if we have no source position info, try to provide as much context
1191 // as possible (if nodes != nil, we don't need this because any errors
1192 // will actually have file and line numbers)
1193 if c.optAggPath != "" {
1194 fmt.Fprintf(&ctx, " at %s", c.optAggPath)
1195 }
1196 }
1197 ctx.WriteString(": ")
1198 }
1199 return ctx.String()
1200}
1201
1202func writeOptionName(buf *bytes.Buffer, parts []*dpb.UninterpretedOption_NamePart) {
1203 first := true
1204 for _, p := range parts {
1205 if first {
1206 first = false
1207 } else {
1208 buf.WriteByte('.')
1209 }
1210 nm := p.GetNamePart()
1211 if nm[0] == '.' {
1212 // skip leading dot
1213 nm = nm[1:]
1214 }
1215 if p.GetIsExtension() {
1216 buf.WriteByte('(')
1217 buf.WriteString(nm)
1218 buf.WriteByte(')')
1219 } else {
1220 buf.WriteString(nm)
1221 }
1222 }
1223}
1224
1225func fieldName(fld *desc.FieldDescriptor) string {
1226 if fld.IsExtension() {
1227 return fld.GetFullyQualifiedName()
1228 } else {
1229 return fld.GetName()
1230 }
1231}
1232
1233func valueKind(val interface{}) string {
1234 switch val := val.(type) {
1235 case identifier:
1236 return "identifier"
1237 case bool:
1238 return "bool"
1239 case int64:
1240 if val < 0 {
1241 return "negative integer"
1242 }
1243 return "integer"
1244 case uint64:
1245 return "integer"
1246 case float64:
1247 return "double"
1248 case string, []byte:
1249 return "string"
1250 case []*aggregateEntryNode:
1251 return "message"
1252 default:
1253 return fmt.Sprintf("%T", val)
1254 }
1255}
1256
1257func fieldValue(res *parseResult, mc *messageContext, fld fldDescriptorish, val valueNode, enumAsString bool) (interface{}, error) {
1258 v := val.value()
1259 t := fld.AsFieldDescriptorProto().GetType()
1260 switch t {
1261 case dpb.FieldDescriptorProto_TYPE_ENUM:
1262 if id, ok := v.(identifier); ok {
1263 ev := fld.GetEnumType().FindValueByName(string(id))
1264 if ev == nil {
1265 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%venum %s has no value named %s", mc, fld.GetEnumType().GetFullyQualifiedName(), id)}
1266 }
1267 if enumAsString {
1268 return ev.GetName(), nil
1269 } else {
1270 return ev.GetNumber(), nil
1271 }
1272 }
1273 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting enum, got %s", mc, valueKind(v))}
1274 case dpb.FieldDescriptorProto_TYPE_MESSAGE, dpb.FieldDescriptorProto_TYPE_GROUP:
1275 if aggs, ok := v.([]*aggregateEntryNode); ok {
1276 fmd := fld.GetMessageType()
1277 fdm := dynamic.NewMessage(fmd)
1278 origPath := mc.optAggPath
1279 defer func() {
1280 mc.optAggPath = origPath
1281 }()
1282 for _, a := range aggs {
1283 if origPath == "" {
1284 mc.optAggPath = a.name.value()
1285 } else {
1286 mc.optAggPath = origPath + "." + a.name.value()
1287 }
1288 var ffld *desc.FieldDescriptor
1289 if a.name.isExtension {
1290 n := a.name.name.val
1291 ffld = findExtension(mc.file, n, false, map[fileDescriptorish]struct{}{})
1292 if ffld == nil {
1293 // may need to qualify with package name
1294 pkg := mc.file.GetPackage()
1295 if pkg != "" {
1296 ffld = findExtension(mc.file, pkg+"."+n, false, map[fileDescriptorish]struct{}{})
1297 }
1298 }
1299 } else {
1300 ffld = fmd.FindFieldByName(a.name.value())
1301 }
1302 if ffld == nil {
1303 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vfield %s not found", mc, a.name.name.val)}
1304 }
1305 if err := setOptionField(res, mc, fdm, ffld, a.name, a.val); err != nil {
1306 return nil, err
1307 }
1308 }
1309 return fdm, nil
1310 }
1311 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting message, got %s", mc, valueKind(v))}
1312 case dpb.FieldDescriptorProto_TYPE_BOOL:
1313 if b, ok := v.(bool); ok {
1314 return b, nil
1315 }
1316 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting bool, got %s", mc, valueKind(v))}
1317 case dpb.FieldDescriptorProto_TYPE_BYTES:
1318 if str, ok := v.(string); ok {
1319 return []byte(str), nil
1320 }
1321 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting bytes, got %s", mc, valueKind(v))}
1322 case dpb.FieldDescriptorProto_TYPE_STRING:
1323 if str, ok := v.(string); ok {
1324 return str, nil
1325 }
1326 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting string, got %s", mc, valueKind(v))}
1327 case dpb.FieldDescriptorProto_TYPE_INT32, dpb.FieldDescriptorProto_TYPE_SINT32, dpb.FieldDescriptorProto_TYPE_SFIXED32:
1328 if i, ok := v.(int64); ok {
1329 if i > math.MaxInt32 || i < math.MinInt32 {
1330 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vvalue %d is out of range for int32", mc, i)}
1331 }
1332 return int32(i), nil
1333 }
1334 if ui, ok := v.(uint64); ok {
1335 if ui > math.MaxInt32 {
1336 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vvalue %d is out of range for int32", mc, ui)}
1337 }
1338 return int32(ui), nil
1339 }
1340 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting int32, got %s", mc, valueKind(v))}
1341 case dpb.FieldDescriptorProto_TYPE_UINT32, dpb.FieldDescriptorProto_TYPE_FIXED32:
1342 if i, ok := v.(int64); ok {
1343 if i > math.MaxUint32 || i < 0 {
1344 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vvalue %d is out of range for uint32", mc, i)}
1345 }
1346 return uint32(i), nil
1347 }
1348 if ui, ok := v.(uint64); ok {
1349 if ui > math.MaxUint32 {
1350 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vvalue %d is out of range for uint32", mc, ui)}
1351 }
1352 return uint32(ui), nil
1353 }
1354 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting uint32, got %s", mc, valueKind(v))}
1355 case dpb.FieldDescriptorProto_TYPE_INT64, dpb.FieldDescriptorProto_TYPE_SINT64, dpb.FieldDescriptorProto_TYPE_SFIXED64:
1356 if i, ok := v.(int64); ok {
1357 return i, nil
1358 }
1359 if ui, ok := v.(uint64); ok {
1360 if ui > math.MaxInt64 {
1361 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vvalue %d is out of range for int64", mc, ui)}
1362 }
1363 return int64(ui), nil
1364 }
1365 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting int64, got %s", mc, valueKind(v))}
1366 case dpb.FieldDescriptorProto_TYPE_UINT64, dpb.FieldDescriptorProto_TYPE_FIXED64:
1367 if i, ok := v.(int64); ok {
1368 if i < 0 {
1369 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vvalue %d is out of range for uint64", mc, i)}
1370 }
1371 return uint64(i), nil
1372 }
1373 if ui, ok := v.(uint64); ok {
1374 return ui, nil
1375 }
1376 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting uint64, got %s", mc, valueKind(v))}
1377 case dpb.FieldDescriptorProto_TYPE_DOUBLE:
1378 if d, ok := v.(float64); ok {
1379 return d, nil
1380 }
1381 if i, ok := v.(int64); ok {
1382 return float64(i), nil
1383 }
1384 if u, ok := v.(uint64); ok {
1385 return float64(u), nil
1386 }
1387 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting double, got %s", mc, valueKind(v))}
1388 case dpb.FieldDescriptorProto_TYPE_FLOAT:
1389 if d, ok := v.(float64); ok {
1390 if (d > math.MaxFloat32 || d < -math.MaxFloat32) && !math.IsInf(d, 1) && !math.IsInf(d, -1) && !math.IsNaN(d) {
1391 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vvalue %f is out of range for float", mc, d)}
1392 }
1393 return float32(d), nil
1394 }
1395 if i, ok := v.(int64); ok {
1396 return float32(i), nil
1397 }
1398 if u, ok := v.(uint64); ok {
1399 return float32(u), nil
1400 }
1401 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vexpecting float, got %s", mc, valueKind(v))}
1402 default:
1403 return nil, ErrorWithSourcePos{Pos: val.start(), Underlying: fmt.Errorf("%vunrecognized field type: %s", mc, t)}
1404 }
1405}