github.com/hoveychen/protoreflect@v1.4.7-0.20221103114119-0b4b3385ec76/desc/protoparse/options.go (about) 1 package protoparse 2 3 import ( 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/hoveychen/protoreflect/desc" 12 "github.com/hoveychen/protoreflect/desc/internal" 13 "github.com/hoveychen/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 21 type descriptorish interface { 22 GetFile() fileDescriptorish 23 GetFullyQualifiedName() string 24 AsProto() proto.Message 25 } 26 27 type 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 40 type 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 51 type fldDescriptorish interface { 52 descriptorish 53 GetFieldOptions() *dpb.FieldOptions 54 GetMessageType() *desc.MessageDescriptor 55 GetEnumType() *desc.EnumDescriptor 56 AsFieldDescriptorProto() *dpb.FieldDescriptorProto 57 } 58 59 type oneofDescriptorish interface { 60 descriptorish 61 GetOneOfOptions() *dpb.OneofOptions 62 } 63 64 type enumDescriptorish interface { 65 descriptorish 66 GetEnumOptions() *dpb.EnumOptions 67 GetValues() []enumValDescriptorish 68 } 69 70 type enumValDescriptorish interface { 71 descriptorish 72 GetEnumValueOptions() *dpb.EnumValueOptions 73 } 74 75 type svcDescriptorish interface { 76 descriptorish 77 GetServiceOptions() *dpb.ServiceOptions 78 GetMethods() []methodDescriptorish 79 } 80 81 type methodDescriptorish interface { 82 descriptorish 83 GetMethodOptions() *dpb.MethodOptions 84 } 85 86 // The hierarchy of descriptorish implementations backed by 87 // rich descriptors: 88 89 type richFileDescriptorish struct { 90 *desc.FileDescriptor 91 } 92 93 func (d richFileDescriptorish) GetFile() fileDescriptorish { 94 return d 95 } 96 97 func (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 106 func (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 115 func (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 124 func (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 133 func (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 142 func (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 151 type richMsgDescriptorish struct { 152 *desc.MessageDescriptor 153 } 154 155 func (d richMsgDescriptorish) GetFile() fileDescriptorish { 156 return richFileDescriptorish{FileDescriptor: d.MessageDescriptor.GetFile()} 157 } 158 159 func (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 168 func (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 177 func (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 192 func (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 201 func (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 210 func (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 219 type richFldDescriptorish struct { 220 *desc.FieldDescriptor 221 } 222 223 func (d richFldDescriptorish) GetFile() fileDescriptorish { 224 return richFileDescriptorish{FileDescriptor: d.FieldDescriptor.GetFile()} 225 } 226 227 func (d richFldDescriptorish) AsFieldDescriptorProto() *dpb.FieldDescriptorProto { 228 return d.FieldDescriptor.AsFieldDescriptorProto() 229 } 230 231 type richOneOfDescriptorish struct { 232 *desc.OneOfDescriptor 233 } 234 235 func (d richOneOfDescriptorish) GetFile() fileDescriptorish { 236 return richFileDescriptorish{FileDescriptor: d.OneOfDescriptor.GetFile()} 237 } 238 239 type richEnumDescriptorish struct { 240 *desc.EnumDescriptor 241 } 242 243 func (d richEnumDescriptorish) GetFile() fileDescriptorish { 244 return richFileDescriptorish{FileDescriptor: d.EnumDescriptor.GetFile()} 245 } 246 247 func (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 256 type richEnumValDescriptorish struct { 257 *desc.EnumValueDescriptor 258 } 259 260 func (d richEnumValDescriptorish) GetFile() fileDescriptorish { 261 return richFileDescriptorish{FileDescriptor: d.EnumValueDescriptor.GetFile()} 262 } 263 264 type richSvcDescriptorish struct { 265 *desc.ServiceDescriptor 266 } 267 268 func (d richSvcDescriptorish) GetFile() fileDescriptorish { 269 return richFileDescriptorish{FileDescriptor: d.ServiceDescriptor.GetFile()} 270 } 271 272 func (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 281 type richMethodDescriptorish struct { 282 *desc.MethodDescriptor 283 } 284 285 func (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 292 type poorFileDescriptorish struct { 293 *dpb.FileDescriptorProto 294 } 295 296 func (d poorFileDescriptorish) GetFile() fileDescriptorish { 297 return d 298 } 299 300 func (d poorFileDescriptorish) GetFullyQualifiedName() string { 301 return d.FileDescriptorProto.GetName() 302 } 303 304 func (d poorFileDescriptorish) AsProto() proto.Message { 305 return d.FileDescriptorProto 306 } 307 308 func (d poorFileDescriptorish) GetFileOptions() *dpb.FileOptions { 309 return d.FileDescriptorProto.GetOptions() 310 } 311 312 func (d poorFileDescriptorish) FindSymbol(name string) desc.Descriptor { 313 return nil 314 } 315 316 func (d poorFileDescriptorish) GetPublicDependencies() []fileDescriptorish { 317 return nil 318 } 319 320 func (d poorFileDescriptorish) GetDependencies() []fileDescriptorish { 321 return nil 322 } 323 324 func (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 338 func (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 352 func (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 366 func (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 380 type poorMsgDescriptorish struct { 381 *dpb.DescriptorProto 382 qual string 383 file fileDescriptorish 384 } 385 386 func (d poorMsgDescriptorish) GetFile() fileDescriptorish { 387 return d.file 388 } 389 390 func (d poorMsgDescriptorish) GetFullyQualifiedName() string { 391 return qualify(d.qual, d.DescriptorProto.GetName()) 392 } 393 394 func qualify(qual, name string) string { 395 if qual == "" { 396 return name 397 } else { 398 return fmt.Sprintf("%s.%s", qual, name) 399 } 400 } 401 402 func (d poorMsgDescriptorish) AsProto() proto.Message { 403 return d.DescriptorProto 404 } 405 406 func (d poorMsgDescriptorish) GetMessageOptions() *dpb.MessageOptions { 407 return d.DescriptorProto.GetOptions() 408 } 409 410 func (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 423 func (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 436 func (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 450 func (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 463 func (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 476 func (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 489 type poorFldDescriptorish struct { 490 *dpb.FieldDescriptorProto 491 qual string 492 file fileDescriptorish 493 } 494 495 func (d poorFldDescriptorish) GetFile() fileDescriptorish { 496 return d.file 497 } 498 499 func (d poorFldDescriptorish) GetFullyQualifiedName() string { 500 return qualify(d.qual, d.FieldDescriptorProto.GetName()) 501 } 502 503 func (d poorFldDescriptorish) AsProto() proto.Message { 504 return d.FieldDescriptorProto 505 } 506 507 func (d poorFldDescriptorish) GetFieldOptions() *dpb.FieldOptions { 508 return d.FieldDescriptorProto.GetOptions() 509 } 510 511 func (d poorFldDescriptorish) GetMessageType() *desc.MessageDescriptor { 512 return nil 513 } 514 515 func (d poorFldDescriptorish) GetEnumType() *desc.EnumDescriptor { 516 return nil 517 } 518 519 type poorOneOfDescriptorish struct { 520 *dpb.OneofDescriptorProto 521 qual string 522 file fileDescriptorish 523 } 524 525 func (d poorOneOfDescriptorish) GetFile() fileDescriptorish { 526 return d.file 527 } 528 529 func (d poorOneOfDescriptorish) GetFullyQualifiedName() string { 530 return qualify(d.qual, d.OneofDescriptorProto.GetName()) 531 } 532 533 func (d poorOneOfDescriptorish) AsProto() proto.Message { 534 return d.OneofDescriptorProto 535 } 536 537 func (d poorOneOfDescriptorish) GetOneOfOptions() *dpb.OneofOptions { 538 return d.OneofDescriptorProto.GetOptions() 539 } 540 541 func (d poorFldDescriptorish) AsFieldDescriptorProto() *dpb.FieldDescriptorProto { 542 return d.FieldDescriptorProto 543 } 544 545 type poorEnumDescriptorish struct { 546 *dpb.EnumDescriptorProto 547 qual string 548 file fileDescriptorish 549 } 550 551 func (d poorEnumDescriptorish) GetFile() fileDescriptorish { 552 return d.file 553 } 554 555 func (d poorEnumDescriptorish) GetFullyQualifiedName() string { 556 return qualify(d.qual, d.EnumDescriptorProto.GetName()) 557 } 558 559 func (d poorEnumDescriptorish) AsProto() proto.Message { 560 return d.EnumDescriptorProto 561 } 562 563 func (d poorEnumDescriptorish) GetEnumOptions() *dpb.EnumOptions { 564 return d.EnumDescriptorProto.GetOptions() 565 } 566 567 func (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 580 type poorEnumValDescriptorish struct { 581 *dpb.EnumValueDescriptorProto 582 qual string 583 file fileDescriptorish 584 } 585 586 func (d poorEnumValDescriptorish) GetFile() fileDescriptorish { 587 return d.file 588 } 589 590 func (d poorEnumValDescriptorish) GetFullyQualifiedName() string { 591 return qualify(d.qual, d.EnumValueDescriptorProto.GetName()) 592 } 593 594 func (d poorEnumValDescriptorish) AsProto() proto.Message { 595 return d.EnumValueDescriptorProto 596 } 597 598 func (d poorEnumValDescriptorish) GetEnumValueOptions() *dpb.EnumValueOptions { 599 return d.EnumValueDescriptorProto.GetOptions() 600 } 601 602 type poorSvcDescriptorish struct { 603 *dpb.ServiceDescriptorProto 604 qual string 605 file fileDescriptorish 606 } 607 608 func (d poorSvcDescriptorish) GetFile() fileDescriptorish { 609 return d.file 610 } 611 612 func (d poorSvcDescriptorish) GetFullyQualifiedName() string { 613 return qualify(d.qual, d.ServiceDescriptorProto.GetName()) 614 } 615 616 func (d poorSvcDescriptorish) AsProto() proto.Message { 617 return d.ServiceDescriptorProto 618 } 619 620 func (d poorSvcDescriptorish) GetServiceOptions() *dpb.ServiceOptions { 621 return d.ServiceDescriptorProto.GetOptions() 622 } 623 624 func (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 637 type poorMethodDescriptorish struct { 638 *dpb.MethodDescriptorProto 639 qual string 640 file fileDescriptorish 641 } 642 643 func (d poorMethodDescriptorish) GetFile() fileDescriptorish { 644 return d.file 645 } 646 647 func (d poorMethodDescriptorish) GetFullyQualifiedName() string { 648 return qualify(d.qual, d.MethodDescriptorProto.GetName()) 649 } 650 651 func (d poorMethodDescriptorish) AsProto() proto.Message { 652 return d.MethodDescriptorProto 653 } 654 655 func (d poorMethodDescriptorish) GetMethodOptions() *dpb.MethodOptions { 656 return d.MethodDescriptorProto.GetOptions() 657 } 658 659 type extRangeDescriptorish struct { 660 er *dpb.DescriptorProto_ExtensionRange 661 qual string 662 file fileDescriptorish 663 } 664 665 func (er extRangeDescriptorish) GetFile() fileDescriptorish { 666 return er.file 667 } 668 669 func (er extRangeDescriptorish) GetFullyQualifiedName() string { 670 return qualify(er.qual, fmt.Sprintf("%d-%d", er.er.GetStart(), er.er.GetEnd()-1)) 671 } 672 673 func (er extRangeDescriptorish) AsProto() proto.Message { 674 return er.er 675 } 676 677 func (er extRangeDescriptorish) GetExtensionRangeOptions() *dpb.ExtensionRangeOptions { 678 return er.er.GetOptions() 679 } 680 681 func 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 734 func 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 792 func 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 842 func 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 903 func encodeDefaultBytes(b []byte) string { 904 var buf bytes.Buffer 905 writeEscapedBytes(&buf, b) 906 return buf.String() 907 } 908 909 func 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 935 func 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 1007 // and fail if not successful 1008 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 1017 func 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 1098 func 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 1131 func 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 1172 type messageContext struct { 1173 res *parseResult 1174 file fileDescriptorish 1175 elementType string 1176 elementName string 1177 option *dpb.UninterpretedOption 1178 optAggPath string 1179 } 1180 1181 func (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 1202 func 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 1225 func fieldName(fld *desc.FieldDescriptor) string { 1226 if fld.IsExtension() { 1227 return fld.GetFullyQualifiedName() 1228 } else { 1229 return fld.GetName() 1230 } 1231 } 1232 1233 func 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 1257 func 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 }