github.com/bakjos/protoreflect@v1.9.2/desc/protoparse/descriptor_protos.go (about) 1 package protoparse 2 3 import ( 4 "bytes" 5 "math" 6 "strings" 7 "unicode" 8 9 "github.com/golang/protobuf/proto" 10 dpb "github.com/golang/protobuf/protoc-gen-go/descriptor" 11 12 "github.com/bakjos/protoreflect/desc/internal" 13 "github.com/bakjos/protoreflect/desc/protoparse/ast" 14 ) 15 16 func (r *parseResult) createFileDescriptor(filename string, file *ast.FileNode) { 17 fd := &dpb.FileDescriptorProto{Name: proto.String(filename)} 18 r.fd = fd 19 r.putFileNode(fd, file) 20 21 isProto3 := false 22 if file.Syntax != nil { 23 if file.Syntax.Syntax.AsString() == "proto3" { 24 isProto3 = true 25 } else if file.Syntax.Syntax.AsString() != "proto2" { 26 if r.errs.handleErrorWithPos(file.Syntax.Syntax.Start(), `syntax value must be "proto2" or "proto3"`) != nil { 27 return 28 } 29 } 30 31 // proto2 is the default, so no need to set unless proto3 32 if isProto3 { 33 fd.Syntax = proto.String(file.Syntax.Syntax.AsString()) 34 } 35 } else { 36 r.errs.warn(file.Start(), ErrNoSyntax) 37 } 38 39 for _, decl := range file.Decls { 40 if r.errs.err != nil { 41 return 42 } 43 switch decl := decl.(type) { 44 case *ast.EnumNode: 45 fd.EnumType = append(fd.EnumType, r.asEnumDescriptor(decl)) 46 case *ast.ExtendNode: 47 r.addExtensions(decl, &fd.Extension, &fd.MessageType, isProto3) 48 case *ast.ImportNode: 49 index := len(fd.Dependency) 50 fd.Dependency = append(fd.Dependency, decl.Name.AsString()) 51 if decl.Public != nil { 52 fd.PublicDependency = append(fd.PublicDependency, int32(index)) 53 } else if decl.Weak != nil { 54 fd.WeakDependency = append(fd.WeakDependency, int32(index)) 55 } 56 case *ast.MessageNode: 57 fd.MessageType = append(fd.MessageType, r.asMessageDescriptor(decl, isProto3)) 58 case *ast.OptionNode: 59 if fd.Options == nil { 60 fd.Options = &dpb.FileOptions{} 61 } 62 fd.Options.UninterpretedOption = append(fd.Options.UninterpretedOption, r.asUninterpretedOption(decl)) 63 case *ast.ServiceNode: 64 fd.Service = append(fd.Service, r.asServiceDescriptor(decl)) 65 case *ast.PackageNode: 66 if fd.Package != nil { 67 if r.errs.handleErrorWithPos(decl.Start(), "files should have only one package declaration") != nil { 68 return 69 } 70 } 71 fd.Package = proto.String(string(decl.Name.AsIdentifier())) 72 } 73 } 74 } 75 76 func (r *parseResult) asUninterpretedOptions(nodes []*ast.OptionNode) []*dpb.UninterpretedOption { 77 if len(nodes) == 0 { 78 return nil 79 } 80 opts := make([]*dpb.UninterpretedOption, len(nodes)) 81 for i, n := range nodes { 82 opts[i] = r.asUninterpretedOption(n) 83 } 84 return opts 85 } 86 87 func (r *parseResult) asUninterpretedOption(node *ast.OptionNode) *dpb.UninterpretedOption { 88 opt := &dpb.UninterpretedOption{Name: r.asUninterpretedOptionName(node.Name.Parts)} 89 r.putOptionNode(opt, node) 90 91 switch val := node.Val.Value().(type) { 92 case bool: 93 if val { 94 opt.IdentifierValue = proto.String("true") 95 } else { 96 opt.IdentifierValue = proto.String("false") 97 } 98 case int64: 99 opt.NegativeIntValue = proto.Int64(val) 100 case uint64: 101 opt.PositiveIntValue = proto.Uint64(val) 102 case float64: 103 opt.DoubleValue = proto.Float64(val) 104 case string: 105 opt.StringValue = []byte(val) 106 case ast.Identifier: 107 opt.IdentifierValue = proto.String(string(val)) 108 case []*ast.MessageFieldNode: 109 var buf bytes.Buffer 110 aggToString(val, &buf) 111 aggStr := buf.String() 112 opt.AggregateValue = proto.String(aggStr) 113 //the grammar does not allow arrays here, so no case for []ast.ValueNode 114 } 115 return opt 116 } 117 118 func (r *parseResult) asUninterpretedOptionName(parts []*ast.FieldReferenceNode) []*dpb.UninterpretedOption_NamePart { 119 ret := make([]*dpb.UninterpretedOption_NamePart, len(parts)) 120 for i, part := range parts { 121 np := &dpb.UninterpretedOption_NamePart{ 122 NamePart: proto.String(string(part.Name.AsIdentifier())), 123 IsExtension: proto.Bool(part.IsExtension()), 124 } 125 r.putOptionNamePartNode(np, part) 126 ret[i] = np 127 } 128 return ret 129 } 130 131 func (r *parseResult) addExtensions(ext *ast.ExtendNode, flds *[]*dpb.FieldDescriptorProto, msgs *[]*dpb.DescriptorProto, isProto3 bool) { 132 extendee := string(ext.Extendee.AsIdentifier()) 133 count := 0 134 for _, decl := range ext.Decls { 135 switch decl := decl.(type) { 136 case *ast.FieldNode: 137 count++ 138 // use higher limit since we don't know yet whether extendee is messageset wire format 139 fd := r.asFieldDescriptor(decl, internal.MaxTag, isProto3) 140 fd.Extendee = proto.String(extendee) 141 *flds = append(*flds, fd) 142 case *ast.GroupNode: 143 count++ 144 // ditto: use higher limit right now 145 fd, md := r.asGroupDescriptors(decl, isProto3, internal.MaxTag) 146 fd.Extendee = proto.String(extendee) 147 *flds = append(*flds, fd) 148 *msgs = append(*msgs, md) 149 } 150 } 151 if count == 0 { 152 _ = r.errs.handleErrorWithPos(ext.Start(), "extend sections must define at least one extension") 153 } 154 } 155 156 func asLabel(lbl *ast.FieldLabel) *dpb.FieldDescriptorProto_Label { 157 if !lbl.IsPresent() { 158 return nil 159 } 160 switch { 161 case lbl.Repeated: 162 return dpb.FieldDescriptorProto_LABEL_REPEATED.Enum() 163 case lbl.Required: 164 return dpb.FieldDescriptorProto_LABEL_REQUIRED.Enum() 165 default: 166 return dpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum() 167 } 168 } 169 170 func (r *parseResult) asFieldDescriptor(node *ast.FieldNode, maxTag int32, isProto3 bool) *dpb.FieldDescriptorProto { 171 tag := node.Tag.Val 172 if err := checkTag(node.Tag.Start(), tag, maxTag); err != nil { 173 _ = r.errs.handleError(err) 174 } 175 fd := newFieldDescriptor(node.Name.Val, string(node.FldType.AsIdentifier()), int32(tag), asLabel(&node.Label)) 176 r.putFieldNode(fd, node) 177 if opts := node.Options.GetElements(); len(opts) > 0 { 178 fd.Options = &dpb.FieldOptions{UninterpretedOption: r.asUninterpretedOptions(opts)} 179 } 180 if isProto3 && fd.Label != nil && fd.GetLabel() == dpb.FieldDescriptorProto_LABEL_OPTIONAL { 181 internal.SetProto3Optional(fd) 182 } 183 return fd 184 } 185 186 var fieldTypes = map[string]dpb.FieldDescriptorProto_Type{ 187 "double": dpb.FieldDescriptorProto_TYPE_DOUBLE, 188 "float": dpb.FieldDescriptorProto_TYPE_FLOAT, 189 "int32": dpb.FieldDescriptorProto_TYPE_INT32, 190 "int64": dpb.FieldDescriptorProto_TYPE_INT64, 191 "uint32": dpb.FieldDescriptorProto_TYPE_UINT32, 192 "uint64": dpb.FieldDescriptorProto_TYPE_UINT64, 193 "sint32": dpb.FieldDescriptorProto_TYPE_SINT32, 194 "sint64": dpb.FieldDescriptorProto_TYPE_SINT64, 195 "fixed32": dpb.FieldDescriptorProto_TYPE_FIXED32, 196 "fixed64": dpb.FieldDescriptorProto_TYPE_FIXED64, 197 "sfixed32": dpb.FieldDescriptorProto_TYPE_SFIXED32, 198 "sfixed64": dpb.FieldDescriptorProto_TYPE_SFIXED64, 199 "bool": dpb.FieldDescriptorProto_TYPE_BOOL, 200 "string": dpb.FieldDescriptorProto_TYPE_STRING, 201 "bytes": dpb.FieldDescriptorProto_TYPE_BYTES, 202 } 203 204 func newFieldDescriptor(name string, fieldType string, tag int32, lbl *dpb.FieldDescriptorProto_Label) *dpb.FieldDescriptorProto { 205 fd := &dpb.FieldDescriptorProto{ 206 Name: proto.String(name), 207 JsonName: proto.String(internal.JsonName(name)), 208 Number: proto.Int32(tag), 209 Label: lbl, 210 } 211 t, ok := fieldTypes[fieldType] 212 if ok { 213 fd.Type = t.Enum() 214 } else { 215 // NB: we don't have enough info to determine whether this is an enum 216 // or a message type, so we'll leave Type nil and set it later 217 // (during linking) 218 fd.TypeName = proto.String(fieldType) 219 } 220 return fd 221 } 222 223 func (r *parseResult) asGroupDescriptors(group *ast.GroupNode, isProto3 bool, maxTag int32) (*dpb.FieldDescriptorProto, *dpb.DescriptorProto) { 224 tag := group.Tag.Val 225 if err := checkTag(group.Tag.Start(), tag, maxTag); err != nil { 226 _ = r.errs.handleError(err) 227 } 228 if !unicode.IsUpper(rune(group.Name.Val[0])) { 229 _ = r.errs.handleErrorWithPos(group.Name.Start(), "group %s should have a name that starts with a capital letter", group.Name.Val) 230 } 231 fieldName := strings.ToLower(group.Name.Val) 232 fd := &dpb.FieldDescriptorProto{ 233 Name: proto.String(fieldName), 234 JsonName: proto.String(internal.JsonName(fieldName)), 235 Number: proto.Int32(int32(tag)), 236 Label: asLabel(&group.Label), 237 Type: dpb.FieldDescriptorProto_TYPE_GROUP.Enum(), 238 TypeName: proto.String(group.Name.Val), 239 } 240 r.putFieldNode(fd, group) 241 if opts := group.Options.GetElements(); len(opts) > 0 { 242 fd.Options = &dpb.FieldOptions{UninterpretedOption: r.asUninterpretedOptions(opts)} 243 } 244 md := &dpb.DescriptorProto{Name: proto.String(group.Name.Val)} 245 r.putMessageNode(md, group) 246 r.addMessageBody(md, &group.MessageBody, isProto3) 247 return fd, md 248 } 249 250 func (r *parseResult) asMapDescriptors(mapField *ast.MapFieldNode, isProto3 bool, maxTag int32) (*dpb.FieldDescriptorProto, *dpb.DescriptorProto) { 251 tag := mapField.Tag.Val 252 if err := checkTag(mapField.Tag.Start(), tag, maxTag); err != nil { 253 _ = r.errs.handleError(err) 254 } 255 var lbl *dpb.FieldDescriptorProto_Label 256 if !isProto3 { 257 lbl = dpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum() 258 } 259 keyFd := newFieldDescriptor("key", mapField.MapType.KeyType.Val, 1, lbl) 260 r.putFieldNode(keyFd, mapField.KeyField()) 261 valFd := newFieldDescriptor("value", string(mapField.MapType.ValueType.AsIdentifier()), 2, lbl) 262 r.putFieldNode(valFd, mapField.ValueField()) 263 entryName := internal.InitCap(internal.JsonName(mapField.Name.Val)) + "Entry" 264 fd := newFieldDescriptor(mapField.Name.Val, entryName, int32(tag), dpb.FieldDescriptorProto_LABEL_REPEATED.Enum()) 265 if opts := mapField.Options.GetElements(); len(opts) > 0 { 266 fd.Options = &dpb.FieldOptions{UninterpretedOption: r.asUninterpretedOptions(opts)} 267 } 268 r.putFieldNode(fd, mapField) 269 md := &dpb.DescriptorProto{ 270 Name: proto.String(entryName), 271 Options: &dpb.MessageOptions{MapEntry: proto.Bool(true)}, 272 Field: []*dpb.FieldDescriptorProto{keyFd, valFd}, 273 } 274 r.putMessageNode(md, mapField) 275 return fd, md 276 } 277 278 func (r *parseResult) asExtensionRanges(node *ast.ExtensionRangeNode, maxTag int32) []*dpb.DescriptorProto_ExtensionRange { 279 opts := r.asUninterpretedOptions(node.Options.GetElements()) 280 ers := make([]*dpb.DescriptorProto_ExtensionRange, len(node.Ranges)) 281 for i, rng := range node.Ranges { 282 start, end := getRangeBounds(r, rng, 0, maxTag) 283 er := &dpb.DescriptorProto_ExtensionRange{ 284 Start: proto.Int32(start), 285 End: proto.Int32(end + 1), 286 } 287 if len(opts) > 0 { 288 er.Options = &dpb.ExtensionRangeOptions{UninterpretedOption: opts} 289 } 290 r.putExtensionRangeNode(er, rng) 291 ers[i] = er 292 } 293 return ers 294 } 295 296 func (r *parseResult) asEnumValue(ev *ast.EnumValueNode) *dpb.EnumValueDescriptorProto { 297 num, ok := ast.AsInt32(ev.Number, math.MinInt32, math.MaxInt32) 298 if !ok { 299 _ = r.errs.handleErrorWithPos(ev.Number.Start(), "value %d is out of range: should be between %d and %d", ev.Number.Value(), math.MinInt32, math.MaxInt32) 300 } 301 evd := &dpb.EnumValueDescriptorProto{Name: proto.String(ev.Name.Val), Number: proto.Int32(num)} 302 r.putEnumValueNode(evd, ev) 303 if opts := ev.Options.GetElements(); len(opts) > 0 { 304 evd.Options = &dpb.EnumValueOptions{UninterpretedOption: r.asUninterpretedOptions(opts)} 305 } 306 return evd 307 } 308 309 func (r *parseResult) asMethodDescriptor(node *ast.RPCNode) *dpb.MethodDescriptorProto { 310 md := &dpb.MethodDescriptorProto{ 311 Name: proto.String(node.Name.Val), 312 InputType: proto.String(string(node.Input.MessageType.AsIdentifier())), 313 OutputType: proto.String(string(node.Output.MessageType.AsIdentifier())), 314 } 315 r.putMethodNode(md, node) 316 if node.Input.Stream != nil { 317 md.ClientStreaming = proto.Bool(true) 318 } 319 if node.Output.Stream != nil { 320 md.ServerStreaming = proto.Bool(true) 321 } 322 // protoc always adds a MethodOptions if there are brackets 323 // We do the same to match protoc as closely as possible 324 // https://github.com/protocolbuffers/protobuf/blob/0c3f43a6190b77f1f68b7425d1b7e1a8257a8d0c/src/google/protobuf/compiler/parser.cc#L2152 325 if node.OpenBrace != nil { 326 md.Options = &dpb.MethodOptions{} 327 for _, decl := range node.Decls { 328 switch decl := decl.(type) { 329 case *ast.OptionNode: 330 md.Options.UninterpretedOption = append(md.Options.UninterpretedOption, r.asUninterpretedOption(decl)) 331 } 332 } 333 } 334 return md 335 } 336 337 func (r *parseResult) asEnumDescriptor(en *ast.EnumNode) *dpb.EnumDescriptorProto { 338 ed := &dpb.EnumDescriptorProto{Name: proto.String(en.Name.Val)} 339 r.putEnumNode(ed, en) 340 for _, decl := range en.Decls { 341 switch decl := decl.(type) { 342 case *ast.OptionNode: 343 if ed.Options == nil { 344 ed.Options = &dpb.EnumOptions{} 345 } 346 ed.Options.UninterpretedOption = append(ed.Options.UninterpretedOption, r.asUninterpretedOption(decl)) 347 case *ast.EnumValueNode: 348 ed.Value = append(ed.Value, r.asEnumValue(decl)) 349 case *ast.ReservedNode: 350 for _, n := range decl.Names { 351 ed.ReservedName = append(ed.ReservedName, n.AsString()) 352 } 353 for _, rng := range decl.Ranges { 354 ed.ReservedRange = append(ed.ReservedRange, r.asEnumReservedRange(rng)) 355 } 356 } 357 } 358 return ed 359 } 360 361 func (r *parseResult) asEnumReservedRange(rng *ast.RangeNode) *dpb.EnumDescriptorProto_EnumReservedRange { 362 start, end := getRangeBounds(r, rng, math.MinInt32, math.MaxInt32) 363 rr := &dpb.EnumDescriptorProto_EnumReservedRange{ 364 Start: proto.Int32(start), 365 End: proto.Int32(end), 366 } 367 r.putEnumReservedRangeNode(rr, rng) 368 return rr 369 } 370 371 func (r *parseResult) asMessageDescriptor(node *ast.MessageNode, isProto3 bool) *dpb.DescriptorProto { 372 msgd := &dpb.DescriptorProto{Name: proto.String(node.Name.Val)} 373 r.putMessageNode(msgd, node) 374 r.addMessageBody(msgd, &node.MessageBody, isProto3) 375 return msgd 376 } 377 378 func (r *parseResult) addMessageBody(msgd *dpb.DescriptorProto, body *ast.MessageBody, isProto3 bool) { 379 // first process any options 380 for _, decl := range body.Decls { 381 if opt, ok := decl.(*ast.OptionNode); ok { 382 if msgd.Options == nil { 383 msgd.Options = &dpb.MessageOptions{} 384 } 385 msgd.Options.UninterpretedOption = append(msgd.Options.UninterpretedOption, r.asUninterpretedOption(opt)) 386 } 387 } 388 389 // now that we have options, we can see if this uses messageset wire format, which 390 // impacts how we validate tag numbers in any fields in the message 391 maxTag := int32(internal.MaxNormalTag) 392 messageSetOpt, err := isMessageSetWireFormat(r, "message "+msgd.GetName(), msgd) 393 if err != nil { 394 return 395 } else if messageSetOpt != nil { 396 maxTag = internal.MaxTag // higher limit for messageset wire format 397 } 398 399 rsvdNames := map[string]int{} 400 401 // now we can process the rest 402 for _, decl := range body.Decls { 403 switch decl := decl.(type) { 404 case *ast.EnumNode: 405 msgd.EnumType = append(msgd.EnumType, r.asEnumDescriptor(decl)) 406 case *ast.ExtendNode: 407 r.addExtensions(decl, &msgd.Extension, &msgd.NestedType, isProto3) 408 case *ast.ExtensionRangeNode: 409 msgd.ExtensionRange = append(msgd.ExtensionRange, r.asExtensionRanges(decl, maxTag)...) 410 case *ast.FieldNode: 411 fd := r.asFieldDescriptor(decl, maxTag, isProto3) 412 msgd.Field = append(msgd.Field, fd) 413 case *ast.MapFieldNode: 414 fd, md := r.asMapDescriptors(decl, isProto3, maxTag) 415 msgd.Field = append(msgd.Field, fd) 416 msgd.NestedType = append(msgd.NestedType, md) 417 case *ast.GroupNode: 418 fd, md := r.asGroupDescriptors(decl, isProto3, maxTag) 419 msgd.Field = append(msgd.Field, fd) 420 msgd.NestedType = append(msgd.NestedType, md) 421 case *ast.OneOfNode: 422 oodIndex := len(msgd.OneofDecl) 423 ood := &dpb.OneofDescriptorProto{Name: proto.String(decl.Name.Val)} 424 r.putOneOfNode(ood, decl) 425 msgd.OneofDecl = append(msgd.OneofDecl, ood) 426 ooFields := 0 427 for _, oodecl := range decl.Decls { 428 switch oodecl := oodecl.(type) { 429 case *ast.OptionNode: 430 if ood.Options == nil { 431 ood.Options = &dpb.OneofOptions{} 432 } 433 ood.Options.UninterpretedOption = append(ood.Options.UninterpretedOption, r.asUninterpretedOption(oodecl)) 434 case *ast.FieldNode: 435 fd := r.asFieldDescriptor(oodecl, maxTag, isProto3) 436 fd.OneofIndex = proto.Int32(int32(oodIndex)) 437 msgd.Field = append(msgd.Field, fd) 438 ooFields++ 439 case *ast.GroupNode: 440 fd, md := r.asGroupDescriptors(oodecl, isProto3, maxTag) 441 fd.OneofIndex = proto.Int32(int32(oodIndex)) 442 msgd.Field = append(msgd.Field, fd) 443 msgd.NestedType = append(msgd.NestedType, md) 444 ooFields++ 445 } 446 } 447 if ooFields == 0 { 448 _ = r.errs.handleErrorWithPos(decl.Start(), "oneof must contain at least one field") 449 } 450 case *ast.MessageNode: 451 msgd.NestedType = append(msgd.NestedType, r.asMessageDescriptor(decl, isProto3)) 452 case *ast.ReservedNode: 453 for _, n := range decl.Names { 454 count := rsvdNames[n.AsString()] 455 if count == 1 { // already seen 456 _ = r.errs.handleErrorWithPos(n.Start(), "name %q is reserved multiple times", n.AsString()) 457 } 458 rsvdNames[n.AsString()] = count + 1 459 msgd.ReservedName = append(msgd.ReservedName, n.AsString()) 460 } 461 for _, rng := range decl.Ranges { 462 msgd.ReservedRange = append(msgd.ReservedRange, r.asMessageReservedRange(rng, maxTag)) 463 } 464 } 465 } 466 467 if messageSetOpt != nil { 468 if len(msgd.Field) > 0 { 469 node := r.getFieldNode(msgd.Field[0]) 470 _ = r.errs.handleErrorWithPos(node.Start(), "messages with message-set wire format cannot contain non-extension fields") 471 } 472 if len(msgd.ExtensionRange) == 0 { 473 node := r.getOptionNode(messageSetOpt) 474 _ = r.errs.handleErrorWithPos(node.Start(), "messages with message-set wire format must contain at least one extension range") 475 } 476 } 477 478 // process any proto3_optional fields 479 if isProto3 { 480 internal.ProcessProto3OptionalFields(msgd) 481 } 482 } 483 484 func isMessageSetWireFormat(res *parseResult, scope string, md *dpb.DescriptorProto) (*dpb.UninterpretedOption, error) { 485 uo := md.GetOptions().GetUninterpretedOption() 486 index, err := findOption(res, scope, uo, "message_set_wire_format") 487 if err != nil { 488 return nil, err 489 } 490 if index == -1 { 491 // no such option 492 return nil, nil 493 } 494 495 opt := uo[index] 496 497 switch opt.GetIdentifierValue() { 498 case "true": 499 return opt, nil 500 case "false": 501 return nil, nil 502 default: 503 optNode := res.getOptionNode(opt) 504 return nil, res.errs.handleErrorWithPos(optNode.GetValue().Start(), "%s: expecting bool value for message_set_wire_format option", scope) 505 } 506 } 507 508 func (r *parseResult) asMessageReservedRange(rng *ast.RangeNode, maxTag int32) *dpb.DescriptorProto_ReservedRange { 509 start, end := getRangeBounds(r, rng, 0, maxTag) 510 rr := &dpb.DescriptorProto_ReservedRange{ 511 Start: proto.Int32(start), 512 End: proto.Int32(end + 1), 513 } 514 r.putMessageReservedRangeNode(rr, rng) 515 return rr 516 } 517 518 func getRangeBounds(res *parseResult, rng *ast.RangeNode, minVal, maxVal int32) (int32, int32) { 519 checkOrder := true 520 start, ok := rng.StartValueAsInt32(minVal, maxVal) 521 if !ok { 522 checkOrder = false 523 _ = res.errs.handleErrorWithPos(rng.StartVal.Start(), "range start %d is out of range: should be between %d and %d", rng.StartValue(), minVal, maxVal) 524 } 525 526 end, ok := rng.EndValueAsInt32(minVal, maxVal) 527 if !ok { 528 checkOrder = false 529 if rng.EndVal != nil { 530 _ = res.errs.handleErrorWithPos(rng.EndVal.Start(), "range end %d is out of range: should be between %d and %d", rng.EndValue(), minVal, maxVal) 531 } 532 } 533 534 if checkOrder && start > end { 535 _ = res.errs.handleErrorWithPos(rng.RangeStart().Start(), "range, %d to %d, is invalid: start must be <= end", start, end) 536 } 537 538 return start, end 539 } 540 541 func (r *parseResult) asServiceDescriptor(svc *ast.ServiceNode) *dpb.ServiceDescriptorProto { 542 sd := &dpb.ServiceDescriptorProto{Name: proto.String(svc.Name.Val)} 543 r.putServiceNode(sd, svc) 544 for _, decl := range svc.Decls { 545 switch decl := decl.(type) { 546 case *ast.OptionNode: 547 if sd.Options == nil { 548 sd.Options = &dpb.ServiceOptions{} 549 } 550 sd.Options.UninterpretedOption = append(sd.Options.UninterpretedOption, r.asUninterpretedOption(decl)) 551 case *ast.RPCNode: 552 sd.Method = append(sd.Method, r.asMethodDescriptor(decl)) 553 } 554 } 555 return sd 556 }