desc_lazy.go (21694B)
1 // Copyright 2019 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package filedesc 6 7 import ( 8 "reflect" 9 "sync" 10 11 "google.golang.org/protobuf/encoding/protowire" 12 "google.golang.org/protobuf/internal/descopts" 13 "google.golang.org/protobuf/internal/genid" 14 "google.golang.org/protobuf/internal/strs" 15 "google.golang.org/protobuf/proto" 16 "google.golang.org/protobuf/reflect/protoreflect" 17 ) 18 19 func (fd *File) lazyRawInit() { 20 fd.unmarshalFull(fd.builder.RawDescriptor) 21 fd.resolveMessages() 22 fd.resolveExtensions() 23 fd.resolveServices() 24 } 25 26 func (file *File) resolveMessages() { 27 var depIdx int32 28 for i := range file.allMessages { 29 md := &file.allMessages[i] 30 31 // Resolve message field dependencies. 32 for j := range md.L2.Fields.List { 33 fd := &md.L2.Fields.List[j] 34 35 // Weak fields are resolved upon actual use. 36 if fd.L1.IsWeak { 37 continue 38 } 39 40 // Resolve message field dependency. 41 switch fd.L1.Kind { 42 case protoreflect.EnumKind: 43 fd.L1.Enum = file.resolveEnumDependency(fd.L1.Enum, listFieldDeps, depIdx) 44 depIdx++ 45 case protoreflect.MessageKind, protoreflect.GroupKind: 46 fd.L1.Message = file.resolveMessageDependency(fd.L1.Message, listFieldDeps, depIdx) 47 depIdx++ 48 } 49 50 // Default is resolved here since it depends on Enum being resolved. 51 if v := fd.L1.Default.val; v.IsValid() { 52 fd.L1.Default = unmarshalDefault(v.Bytes(), fd.L1.Kind, file, fd.L1.Enum) 53 } 54 } 55 } 56 } 57 58 func (file *File) resolveExtensions() { 59 var depIdx int32 60 for i := range file.allExtensions { 61 xd := &file.allExtensions[i] 62 63 // Resolve extension field dependency. 64 switch xd.L1.Kind { 65 case protoreflect.EnumKind: 66 xd.L2.Enum = file.resolveEnumDependency(xd.L2.Enum, listExtDeps, depIdx) 67 depIdx++ 68 case protoreflect.MessageKind, protoreflect.GroupKind: 69 xd.L2.Message = file.resolveMessageDependency(xd.L2.Message, listExtDeps, depIdx) 70 depIdx++ 71 } 72 73 // Default is resolved here since it depends on Enum being resolved. 74 if v := xd.L2.Default.val; v.IsValid() { 75 xd.L2.Default = unmarshalDefault(v.Bytes(), xd.L1.Kind, file, xd.L2.Enum) 76 } 77 } 78 } 79 80 func (file *File) resolveServices() { 81 var depIdx int32 82 for i := range file.allServices { 83 sd := &file.allServices[i] 84 85 // Resolve method dependencies. 86 for j := range sd.L2.Methods.List { 87 md := &sd.L2.Methods.List[j] 88 md.L1.Input = file.resolveMessageDependency(md.L1.Input, listMethInDeps, depIdx) 89 md.L1.Output = file.resolveMessageDependency(md.L1.Output, listMethOutDeps, depIdx) 90 depIdx++ 91 } 92 } 93 } 94 95 func (file *File) resolveEnumDependency(ed protoreflect.EnumDescriptor, i, j int32) protoreflect.EnumDescriptor { 96 r := file.builder.FileRegistry 97 if r, ok := r.(resolverByIndex); ok { 98 if ed2 := r.FindEnumByIndex(i, j, file.allEnums, file.allMessages); ed2 != nil { 99 return ed2 100 } 101 } 102 for i := range file.allEnums { 103 if ed2 := &file.allEnums[i]; ed2.L0.FullName == ed.FullName() { 104 return ed2 105 } 106 } 107 if d, _ := r.FindDescriptorByName(ed.FullName()); d != nil { 108 return d.(protoreflect.EnumDescriptor) 109 } 110 return ed 111 } 112 113 func (file *File) resolveMessageDependency(md protoreflect.MessageDescriptor, i, j int32) protoreflect.MessageDescriptor { 114 r := file.builder.FileRegistry 115 if r, ok := r.(resolverByIndex); ok { 116 if md2 := r.FindMessageByIndex(i, j, file.allEnums, file.allMessages); md2 != nil { 117 return md2 118 } 119 } 120 for i := range file.allMessages { 121 if md2 := &file.allMessages[i]; md2.L0.FullName == md.FullName() { 122 return md2 123 } 124 } 125 if d, _ := r.FindDescriptorByName(md.FullName()); d != nil { 126 return d.(protoreflect.MessageDescriptor) 127 } 128 return md 129 } 130 131 func (fd *File) unmarshalFull(b []byte) { 132 sb := getBuilder() 133 defer putBuilder(sb) 134 135 var enumIdx, messageIdx, extensionIdx, serviceIdx int 136 var rawOptions []byte 137 fd.L2 = new(FileL2) 138 for len(b) > 0 { 139 num, typ, n := protowire.ConsumeTag(b) 140 b = b[n:] 141 switch typ { 142 case protowire.VarintType: 143 v, m := protowire.ConsumeVarint(b) 144 b = b[m:] 145 switch num { 146 case genid.FileDescriptorProto_PublicDependency_field_number: 147 fd.L2.Imports[v].IsPublic = true 148 case genid.FileDescriptorProto_WeakDependency_field_number: 149 fd.L2.Imports[v].IsWeak = true 150 } 151 case protowire.BytesType: 152 v, m := protowire.ConsumeBytes(b) 153 b = b[m:] 154 switch num { 155 case genid.FileDescriptorProto_Dependency_field_number: 156 path := sb.MakeString(v) 157 imp, _ := fd.builder.FileRegistry.FindFileByPath(path) 158 if imp == nil { 159 imp = PlaceholderFile(path) 160 } 161 fd.L2.Imports = append(fd.L2.Imports, protoreflect.FileImport{FileDescriptor: imp}) 162 case genid.FileDescriptorProto_EnumType_field_number: 163 fd.L1.Enums.List[enumIdx].unmarshalFull(v, sb) 164 enumIdx++ 165 case genid.FileDescriptorProto_MessageType_field_number: 166 fd.L1.Messages.List[messageIdx].unmarshalFull(v, sb) 167 messageIdx++ 168 case genid.FileDescriptorProto_Extension_field_number: 169 fd.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb) 170 extensionIdx++ 171 case genid.FileDescriptorProto_Service_field_number: 172 fd.L1.Services.List[serviceIdx].unmarshalFull(v, sb) 173 serviceIdx++ 174 case genid.FileDescriptorProto_Options_field_number: 175 rawOptions = appendOptions(rawOptions, v) 176 } 177 default: 178 m := protowire.ConsumeFieldValue(num, typ, b) 179 b = b[m:] 180 } 181 } 182 fd.L2.Options = fd.builder.optionsUnmarshaler(&descopts.File, rawOptions) 183 } 184 185 func (ed *Enum) unmarshalFull(b []byte, sb *strs.Builder) { 186 var rawValues [][]byte 187 var rawOptions []byte 188 if !ed.L1.eagerValues { 189 ed.L2 = new(EnumL2) 190 } 191 for len(b) > 0 { 192 num, typ, n := protowire.ConsumeTag(b) 193 b = b[n:] 194 switch typ { 195 case protowire.BytesType: 196 v, m := protowire.ConsumeBytes(b) 197 b = b[m:] 198 switch num { 199 case genid.EnumDescriptorProto_Value_field_number: 200 rawValues = append(rawValues, v) 201 case genid.EnumDescriptorProto_ReservedName_field_number: 202 ed.L2.ReservedNames.List = append(ed.L2.ReservedNames.List, protoreflect.Name(sb.MakeString(v))) 203 case genid.EnumDescriptorProto_ReservedRange_field_number: 204 ed.L2.ReservedRanges.List = append(ed.L2.ReservedRanges.List, unmarshalEnumReservedRange(v)) 205 case genid.EnumDescriptorProto_Options_field_number: 206 rawOptions = appendOptions(rawOptions, v) 207 } 208 default: 209 m := protowire.ConsumeFieldValue(num, typ, b) 210 b = b[m:] 211 } 212 } 213 if !ed.L1.eagerValues && len(rawValues) > 0 { 214 ed.L2.Values.List = make([]EnumValue, len(rawValues)) 215 for i, b := range rawValues { 216 ed.L2.Values.List[i].unmarshalFull(b, sb, ed.L0.ParentFile, ed, i) 217 } 218 } 219 ed.L2.Options = ed.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Enum, rawOptions) 220 } 221 222 func unmarshalEnumReservedRange(b []byte) (r [2]protoreflect.EnumNumber) { 223 for len(b) > 0 { 224 num, typ, n := protowire.ConsumeTag(b) 225 b = b[n:] 226 switch typ { 227 case protowire.VarintType: 228 v, m := protowire.ConsumeVarint(b) 229 b = b[m:] 230 switch num { 231 case genid.EnumDescriptorProto_EnumReservedRange_Start_field_number: 232 r[0] = protoreflect.EnumNumber(v) 233 case genid.EnumDescriptorProto_EnumReservedRange_End_field_number: 234 r[1] = protoreflect.EnumNumber(v) 235 } 236 default: 237 m := protowire.ConsumeFieldValue(num, typ, b) 238 b = b[m:] 239 } 240 } 241 return r 242 } 243 244 func (vd *EnumValue) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) { 245 vd.L0.ParentFile = pf 246 vd.L0.Parent = pd 247 vd.L0.Index = i 248 249 var rawOptions []byte 250 for len(b) > 0 { 251 num, typ, n := protowire.ConsumeTag(b) 252 b = b[n:] 253 switch typ { 254 case protowire.VarintType: 255 v, m := protowire.ConsumeVarint(b) 256 b = b[m:] 257 switch num { 258 case genid.EnumValueDescriptorProto_Number_field_number: 259 vd.L1.Number = protoreflect.EnumNumber(v) 260 } 261 case protowire.BytesType: 262 v, m := protowire.ConsumeBytes(b) 263 b = b[m:] 264 switch num { 265 case genid.EnumValueDescriptorProto_Name_field_number: 266 // NOTE: Enum values are in the same scope as the enum parent. 267 vd.L0.FullName = appendFullName(sb, pd.Parent().FullName(), v) 268 case genid.EnumValueDescriptorProto_Options_field_number: 269 rawOptions = appendOptions(rawOptions, v) 270 } 271 default: 272 m := protowire.ConsumeFieldValue(num, typ, b) 273 b = b[m:] 274 } 275 } 276 vd.L1.Options = pf.builder.optionsUnmarshaler(&descopts.EnumValue, rawOptions) 277 } 278 279 func (md *Message) unmarshalFull(b []byte, sb *strs.Builder) { 280 var rawFields, rawOneofs [][]byte 281 var enumIdx, messageIdx, extensionIdx int 282 var rawOptions []byte 283 md.L2 = new(MessageL2) 284 for len(b) > 0 { 285 num, typ, n := protowire.ConsumeTag(b) 286 b = b[n:] 287 switch typ { 288 case protowire.BytesType: 289 v, m := protowire.ConsumeBytes(b) 290 b = b[m:] 291 switch num { 292 case genid.DescriptorProto_Field_field_number: 293 rawFields = append(rawFields, v) 294 case genid.DescriptorProto_OneofDecl_field_number: 295 rawOneofs = append(rawOneofs, v) 296 case genid.DescriptorProto_ReservedName_field_number: 297 md.L2.ReservedNames.List = append(md.L2.ReservedNames.List, protoreflect.Name(sb.MakeString(v))) 298 case genid.DescriptorProto_ReservedRange_field_number: 299 md.L2.ReservedRanges.List = append(md.L2.ReservedRanges.List, unmarshalMessageReservedRange(v)) 300 case genid.DescriptorProto_ExtensionRange_field_number: 301 r, rawOptions := unmarshalMessageExtensionRange(v) 302 opts := md.L0.ParentFile.builder.optionsUnmarshaler(&descopts.ExtensionRange, rawOptions) 303 md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, r) 304 md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, opts) 305 case genid.DescriptorProto_EnumType_field_number: 306 md.L1.Enums.List[enumIdx].unmarshalFull(v, sb) 307 enumIdx++ 308 case genid.DescriptorProto_NestedType_field_number: 309 md.L1.Messages.List[messageIdx].unmarshalFull(v, sb) 310 messageIdx++ 311 case genid.DescriptorProto_Extension_field_number: 312 md.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb) 313 extensionIdx++ 314 case genid.DescriptorProto_Options_field_number: 315 md.unmarshalOptions(v) 316 rawOptions = appendOptions(rawOptions, v) 317 } 318 default: 319 m := protowire.ConsumeFieldValue(num, typ, b) 320 b = b[m:] 321 } 322 } 323 if len(rawFields) > 0 || len(rawOneofs) > 0 { 324 md.L2.Fields.List = make([]Field, len(rawFields)) 325 md.L2.Oneofs.List = make([]Oneof, len(rawOneofs)) 326 for i, b := range rawFields { 327 fd := &md.L2.Fields.List[i] 328 fd.unmarshalFull(b, sb, md.L0.ParentFile, md, i) 329 if fd.L1.Cardinality == protoreflect.Required { 330 md.L2.RequiredNumbers.List = append(md.L2.RequiredNumbers.List, fd.L1.Number) 331 } 332 } 333 for i, b := range rawOneofs { 334 od := &md.L2.Oneofs.List[i] 335 od.unmarshalFull(b, sb, md.L0.ParentFile, md, i) 336 } 337 } 338 md.L2.Options = md.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Message, rawOptions) 339 } 340 341 func (md *Message) unmarshalOptions(b []byte) { 342 for len(b) > 0 { 343 num, typ, n := protowire.ConsumeTag(b) 344 b = b[n:] 345 switch typ { 346 case protowire.VarintType: 347 v, m := protowire.ConsumeVarint(b) 348 b = b[m:] 349 switch num { 350 case genid.MessageOptions_MapEntry_field_number: 351 md.L1.IsMapEntry = protowire.DecodeBool(v) 352 case genid.MessageOptions_MessageSetWireFormat_field_number: 353 md.L1.IsMessageSet = protowire.DecodeBool(v) 354 } 355 default: 356 m := protowire.ConsumeFieldValue(num, typ, b) 357 b = b[m:] 358 } 359 } 360 } 361 362 func unmarshalMessageReservedRange(b []byte) (r [2]protoreflect.FieldNumber) { 363 for len(b) > 0 { 364 num, typ, n := protowire.ConsumeTag(b) 365 b = b[n:] 366 switch typ { 367 case protowire.VarintType: 368 v, m := protowire.ConsumeVarint(b) 369 b = b[m:] 370 switch num { 371 case genid.DescriptorProto_ReservedRange_Start_field_number: 372 r[0] = protoreflect.FieldNumber(v) 373 case genid.DescriptorProto_ReservedRange_End_field_number: 374 r[1] = protoreflect.FieldNumber(v) 375 } 376 default: 377 m := protowire.ConsumeFieldValue(num, typ, b) 378 b = b[m:] 379 } 380 } 381 return r 382 } 383 384 func unmarshalMessageExtensionRange(b []byte) (r [2]protoreflect.FieldNumber, rawOptions []byte) { 385 for len(b) > 0 { 386 num, typ, n := protowire.ConsumeTag(b) 387 b = b[n:] 388 switch typ { 389 case protowire.VarintType: 390 v, m := protowire.ConsumeVarint(b) 391 b = b[m:] 392 switch num { 393 case genid.DescriptorProto_ExtensionRange_Start_field_number: 394 r[0] = protoreflect.FieldNumber(v) 395 case genid.DescriptorProto_ExtensionRange_End_field_number: 396 r[1] = protoreflect.FieldNumber(v) 397 } 398 case protowire.BytesType: 399 v, m := protowire.ConsumeBytes(b) 400 b = b[m:] 401 switch num { 402 case genid.DescriptorProto_ExtensionRange_Options_field_number: 403 rawOptions = appendOptions(rawOptions, v) 404 } 405 default: 406 m := protowire.ConsumeFieldValue(num, typ, b) 407 b = b[m:] 408 } 409 } 410 return r, rawOptions 411 } 412 413 func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) { 414 fd.L0.ParentFile = pf 415 fd.L0.Parent = pd 416 fd.L0.Index = i 417 418 var rawTypeName []byte 419 var rawOptions []byte 420 for len(b) > 0 { 421 num, typ, n := protowire.ConsumeTag(b) 422 b = b[n:] 423 switch typ { 424 case protowire.VarintType: 425 v, m := protowire.ConsumeVarint(b) 426 b = b[m:] 427 switch num { 428 case genid.FieldDescriptorProto_Number_field_number: 429 fd.L1.Number = protoreflect.FieldNumber(v) 430 case genid.FieldDescriptorProto_Label_field_number: 431 fd.L1.Cardinality = protoreflect.Cardinality(v) 432 case genid.FieldDescriptorProto_Type_field_number: 433 fd.L1.Kind = protoreflect.Kind(v) 434 case genid.FieldDescriptorProto_OneofIndex_field_number: 435 // In Message.unmarshalFull, we allocate slices for both 436 // the field and oneof descriptors before unmarshaling either 437 // of them. This ensures pointers to slice elements are stable. 438 od := &pd.(*Message).L2.Oneofs.List[v] 439 od.L1.Fields.List = append(od.L1.Fields.List, fd) 440 if fd.L1.ContainingOneof != nil { 441 panic("oneof type already set") 442 } 443 fd.L1.ContainingOneof = od 444 case genid.FieldDescriptorProto_Proto3Optional_field_number: 445 fd.L1.IsProto3Optional = protowire.DecodeBool(v) 446 } 447 case protowire.BytesType: 448 v, m := protowire.ConsumeBytes(b) 449 b = b[m:] 450 switch num { 451 case genid.FieldDescriptorProto_Name_field_number: 452 fd.L0.FullName = appendFullName(sb, pd.FullName(), v) 453 case genid.FieldDescriptorProto_JsonName_field_number: 454 fd.L1.StringName.InitJSON(sb.MakeString(v)) 455 case genid.FieldDescriptorProto_DefaultValue_field_number: 456 fd.L1.Default.val = protoreflect.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveMessages 457 case genid.FieldDescriptorProto_TypeName_field_number: 458 rawTypeName = v 459 case genid.FieldDescriptorProto_Options_field_number: 460 fd.unmarshalOptions(v) 461 rawOptions = appendOptions(rawOptions, v) 462 } 463 default: 464 m := protowire.ConsumeFieldValue(num, typ, b) 465 b = b[m:] 466 } 467 } 468 if rawTypeName != nil { 469 name := makeFullName(sb, rawTypeName) 470 switch fd.L1.Kind { 471 case protoreflect.EnumKind: 472 fd.L1.Enum = PlaceholderEnum(name) 473 case protoreflect.MessageKind, protoreflect.GroupKind: 474 fd.L1.Message = PlaceholderMessage(name) 475 } 476 } 477 fd.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Field, rawOptions) 478 } 479 480 func (fd *Field) unmarshalOptions(b []byte) { 481 const FieldOptions_EnforceUTF8 = 13 482 483 for len(b) > 0 { 484 num, typ, n := protowire.ConsumeTag(b) 485 b = b[n:] 486 switch typ { 487 case protowire.VarintType: 488 v, m := protowire.ConsumeVarint(b) 489 b = b[m:] 490 switch num { 491 case genid.FieldOptions_Packed_field_number: 492 fd.L1.HasPacked = true 493 fd.L1.IsPacked = protowire.DecodeBool(v) 494 case genid.FieldOptions_Weak_field_number: 495 fd.L1.IsWeak = protowire.DecodeBool(v) 496 case FieldOptions_EnforceUTF8: 497 fd.L1.HasEnforceUTF8 = true 498 fd.L1.EnforceUTF8 = protowire.DecodeBool(v) 499 } 500 default: 501 m := protowire.ConsumeFieldValue(num, typ, b) 502 b = b[m:] 503 } 504 } 505 } 506 507 func (od *Oneof) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) { 508 od.L0.ParentFile = pf 509 od.L0.Parent = pd 510 od.L0.Index = i 511 512 var rawOptions []byte 513 for len(b) > 0 { 514 num, typ, n := protowire.ConsumeTag(b) 515 b = b[n:] 516 switch typ { 517 case protowire.BytesType: 518 v, m := protowire.ConsumeBytes(b) 519 b = b[m:] 520 switch num { 521 case genid.OneofDescriptorProto_Name_field_number: 522 od.L0.FullName = appendFullName(sb, pd.FullName(), v) 523 case genid.OneofDescriptorProto_Options_field_number: 524 rawOptions = appendOptions(rawOptions, v) 525 } 526 default: 527 m := protowire.ConsumeFieldValue(num, typ, b) 528 b = b[m:] 529 } 530 } 531 od.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Oneof, rawOptions) 532 } 533 534 func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) { 535 var rawTypeName []byte 536 var rawOptions []byte 537 xd.L2 = new(ExtensionL2) 538 for len(b) > 0 { 539 num, typ, n := protowire.ConsumeTag(b) 540 b = b[n:] 541 switch typ { 542 case protowire.VarintType: 543 v, m := protowire.ConsumeVarint(b) 544 b = b[m:] 545 switch num { 546 case genid.FieldDescriptorProto_Proto3Optional_field_number: 547 xd.L2.IsProto3Optional = protowire.DecodeBool(v) 548 } 549 case protowire.BytesType: 550 v, m := protowire.ConsumeBytes(b) 551 b = b[m:] 552 switch num { 553 case genid.FieldDescriptorProto_JsonName_field_number: 554 xd.L2.StringName.InitJSON(sb.MakeString(v)) 555 case genid.FieldDescriptorProto_DefaultValue_field_number: 556 xd.L2.Default.val = protoreflect.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveExtensions 557 case genid.FieldDescriptorProto_TypeName_field_number: 558 rawTypeName = v 559 case genid.FieldDescriptorProto_Options_field_number: 560 xd.unmarshalOptions(v) 561 rawOptions = appendOptions(rawOptions, v) 562 } 563 default: 564 m := protowire.ConsumeFieldValue(num, typ, b) 565 b = b[m:] 566 } 567 } 568 if rawTypeName != nil { 569 name := makeFullName(sb, rawTypeName) 570 switch xd.L1.Kind { 571 case protoreflect.EnumKind: 572 xd.L2.Enum = PlaceholderEnum(name) 573 case protoreflect.MessageKind, protoreflect.GroupKind: 574 xd.L2.Message = PlaceholderMessage(name) 575 } 576 } 577 xd.L2.Options = xd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Field, rawOptions) 578 } 579 580 func (xd *Extension) unmarshalOptions(b []byte) { 581 for len(b) > 0 { 582 num, typ, n := protowire.ConsumeTag(b) 583 b = b[n:] 584 switch typ { 585 case protowire.VarintType: 586 v, m := protowire.ConsumeVarint(b) 587 b = b[m:] 588 switch num { 589 case genid.FieldOptions_Packed_field_number: 590 xd.L2.IsPacked = protowire.DecodeBool(v) 591 } 592 default: 593 m := protowire.ConsumeFieldValue(num, typ, b) 594 b = b[m:] 595 } 596 } 597 } 598 599 func (sd *Service) unmarshalFull(b []byte, sb *strs.Builder) { 600 var rawMethods [][]byte 601 var rawOptions []byte 602 sd.L2 = new(ServiceL2) 603 for len(b) > 0 { 604 num, typ, n := protowire.ConsumeTag(b) 605 b = b[n:] 606 switch typ { 607 case protowire.BytesType: 608 v, m := protowire.ConsumeBytes(b) 609 b = b[m:] 610 switch num { 611 case genid.ServiceDescriptorProto_Method_field_number: 612 rawMethods = append(rawMethods, v) 613 case genid.ServiceDescriptorProto_Options_field_number: 614 rawOptions = appendOptions(rawOptions, v) 615 } 616 default: 617 m := protowire.ConsumeFieldValue(num, typ, b) 618 b = b[m:] 619 } 620 } 621 if len(rawMethods) > 0 { 622 sd.L2.Methods.List = make([]Method, len(rawMethods)) 623 for i, b := range rawMethods { 624 sd.L2.Methods.List[i].unmarshalFull(b, sb, sd.L0.ParentFile, sd, i) 625 } 626 } 627 sd.L2.Options = sd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Service, rawOptions) 628 } 629 630 func (md *Method) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) { 631 md.L0.ParentFile = pf 632 md.L0.Parent = pd 633 md.L0.Index = i 634 635 var rawOptions []byte 636 for len(b) > 0 { 637 num, typ, n := protowire.ConsumeTag(b) 638 b = b[n:] 639 switch typ { 640 case protowire.VarintType: 641 v, m := protowire.ConsumeVarint(b) 642 b = b[m:] 643 switch num { 644 case genid.MethodDescriptorProto_ClientStreaming_field_number: 645 md.L1.IsStreamingClient = protowire.DecodeBool(v) 646 case genid.MethodDescriptorProto_ServerStreaming_field_number: 647 md.L1.IsStreamingServer = protowire.DecodeBool(v) 648 } 649 case protowire.BytesType: 650 v, m := protowire.ConsumeBytes(b) 651 b = b[m:] 652 switch num { 653 case genid.MethodDescriptorProto_Name_field_number: 654 md.L0.FullName = appendFullName(sb, pd.FullName(), v) 655 case genid.MethodDescriptorProto_InputType_field_number: 656 md.L1.Input = PlaceholderMessage(makeFullName(sb, v)) 657 case genid.MethodDescriptorProto_OutputType_field_number: 658 md.L1.Output = PlaceholderMessage(makeFullName(sb, v)) 659 case genid.MethodDescriptorProto_Options_field_number: 660 rawOptions = appendOptions(rawOptions, v) 661 } 662 default: 663 m := protowire.ConsumeFieldValue(num, typ, b) 664 b = b[m:] 665 } 666 } 667 md.L1.Options = pf.builder.optionsUnmarshaler(&descopts.Method, rawOptions) 668 } 669 670 // appendOptions appends src to dst, where the returned slice is never nil. 671 // This is necessary to distinguish between empty and unpopulated options. 672 func appendOptions(dst, src []byte) []byte { 673 if dst == nil { 674 dst = []byte{} 675 } 676 return append(dst, src...) 677 } 678 679 // optionsUnmarshaler constructs a lazy unmarshal function for an options message. 680 // 681 // The type of message to unmarshal to is passed as a pointer since the 682 // vars in descopts may not yet be populated at the time this function is called. 683 func (db *Builder) optionsUnmarshaler(p *protoreflect.ProtoMessage, b []byte) func() protoreflect.ProtoMessage { 684 if b == nil { 685 return nil 686 } 687 var opts protoreflect.ProtoMessage 688 var once sync.Once 689 return func() protoreflect.ProtoMessage { 690 once.Do(func() { 691 if *p == nil { 692 panic("Descriptor.Options called without importing the descriptor package") 693 } 694 opts = reflect.New(reflect.TypeOf(*p).Elem()).Interface().(protoreflect.ProtoMessage) 695 if err := (proto.UnmarshalOptions{ 696 AllowPartial: true, 697 Resolver: db.TypeResolver, 698 }).Unmarshal(b, opts); err != nil { 699 panic(err) 700 } 701 }) 702 return opts 703 } 704 }