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