github.com/jhump/protoreflect@v1.16.0/desc/protoparse/ast/field.go (about) 1 package ast 2 3 import "fmt" 4 5 // FieldDeclNode is a node in the AST that defines a field. This includes 6 // normal message fields as well as extensions. There are multiple types 7 // of AST nodes that declare fields: 8 // - *FieldNode 9 // - *GroupNode 10 // - *MapFieldNode 11 // - *SyntheticMapField 12 // 13 // This also allows NoSourceNode to be used in place of one of the above 14 // for some usages. 15 type FieldDeclNode interface { 16 Node 17 FieldLabel() Node 18 FieldName() Node 19 FieldType() Node 20 FieldTag() Node 21 FieldExtendee() Node 22 GetGroupKeyword() Node 23 GetOptions() *CompactOptionsNode 24 } 25 26 var _ FieldDeclNode = (*FieldNode)(nil) 27 var _ FieldDeclNode = (*GroupNode)(nil) 28 var _ FieldDeclNode = (*MapFieldNode)(nil) 29 var _ FieldDeclNode = (*SyntheticMapField)(nil) 30 var _ FieldDeclNode = NoSourceNode{} 31 32 // FieldNode represents a normal field declaration (not groups or maps). It 33 // can represent extension fields as well as non-extension fields (both inside 34 // of messages and inside of one-ofs). Example: 35 // 36 // optional string foo = 1; 37 type FieldNode struct { 38 compositeNode 39 Label FieldLabel 40 FldType IdentValueNode 41 Name *IdentNode 42 Equals *RuneNode 43 Tag *UintLiteralNode 44 Options *CompactOptionsNode 45 Semicolon *RuneNode 46 47 // This is an up-link to the containing *ExtendNode for fields 48 // that are defined inside of "extend" blocks. 49 Extendee *ExtendNode 50 } 51 52 func (*FieldNode) msgElement() {} 53 func (*FieldNode) oneOfElement() {} 54 func (*FieldNode) extendElement() {} 55 56 // NewFieldNode creates a new *FieldNode. The label and options arguments may be 57 // nil but the others must be non-nil. 58 // - label: The token corresponding to the label keyword if present ("optional", 59 // "required", or "repeated"). 60 // - fieldType: The token corresponding to the field's type. 61 // - name: The token corresponding to the field's name. 62 // - equals: The token corresponding to the '=' rune after the name. 63 // - tag: The token corresponding to the field's tag number. 64 // - opts: Optional set of field options. 65 // - semicolon: The token corresponding to the ";" rune that ends the declaration. 66 func NewFieldNode(label *KeywordNode, fieldType IdentValueNode, name *IdentNode, equals *RuneNode, tag *UintLiteralNode, opts *CompactOptionsNode, semicolon *RuneNode) *FieldNode { 67 if fieldType == nil { 68 panic("fieldType is nil") 69 } 70 if name == nil { 71 panic("name is nil") 72 } 73 if equals == nil { 74 panic("equals is nil") 75 } 76 if tag == nil { 77 panic("tag is nil") 78 } 79 if semicolon == nil { 80 panic("semicolon is nil") 81 } 82 numChildren := 5 83 if label != nil { 84 numChildren++ 85 } 86 if opts != nil { 87 numChildren++ 88 } 89 children := make([]Node, 0, numChildren) 90 if label != nil { 91 children = append(children, label) 92 } 93 children = append(children, fieldType, name, equals, tag) 94 if opts != nil { 95 children = append(children, opts) 96 } 97 children = append(children, semicolon) 98 99 return &FieldNode{ 100 compositeNode: compositeNode{ 101 children: children, 102 }, 103 Label: newFieldLabel(label), 104 FldType: fieldType, 105 Name: name, 106 Equals: equals, 107 Tag: tag, 108 Options: opts, 109 Semicolon: semicolon, 110 } 111 } 112 113 func (n *FieldNode) FieldLabel() Node { 114 // proto3 fields and fields inside one-ofs will not have a label and we need 115 // this check in order to return a nil node -- otherwise we'd return a 116 // non-nil node that has a nil pointer value in it :/ 117 if n.Label.KeywordNode == nil { 118 return nil 119 } 120 return n.Label.KeywordNode 121 } 122 123 func (n *FieldNode) FieldName() Node { 124 return n.Name 125 } 126 127 func (n *FieldNode) FieldType() Node { 128 return n.FldType 129 } 130 131 func (n *FieldNode) FieldTag() Node { 132 return n.Tag 133 } 134 135 func (n *FieldNode) FieldExtendee() Node { 136 if n.Extendee != nil { 137 return n.Extendee.Extendee 138 } 139 return nil 140 } 141 142 func (n *FieldNode) GetGroupKeyword() Node { 143 return nil 144 } 145 146 func (n *FieldNode) GetOptions() *CompactOptionsNode { 147 return n.Options 148 } 149 150 // FieldLabel represents the label of a field, which indicates its cardinality 151 // (i.e. whether it is optional, required, or repeated). 152 type FieldLabel struct { 153 *KeywordNode 154 Repeated bool 155 Required bool 156 } 157 158 func newFieldLabel(lbl *KeywordNode) FieldLabel { 159 repeated, required := false, false 160 if lbl != nil { 161 repeated = lbl.Val == "repeated" 162 required = lbl.Val == "required" 163 } 164 return FieldLabel{ 165 KeywordNode: lbl, 166 Repeated: repeated, 167 Required: required, 168 } 169 } 170 171 // IsPresent returns true if a label keyword was present in the declaration 172 // and false if it was absent. 173 func (f *FieldLabel) IsPresent() bool { 174 return f.KeywordNode != nil 175 } 176 177 // GroupNode represents a group declaration, which doubles as a field and inline 178 // message declaration. It can represent extension fields as well as 179 // non-extension fields (both inside of messages and inside of one-ofs). 180 // Example: 181 // 182 // optional group Key = 4 { 183 // optional uint64 id = 1; 184 // optional string name = 2; 185 // } 186 type GroupNode struct { 187 compositeNode 188 Label FieldLabel 189 Keyword *KeywordNode 190 Name *IdentNode 191 Equals *RuneNode 192 Tag *UintLiteralNode 193 Options *CompactOptionsNode 194 MessageBody 195 196 // This is an up-link to the containing *ExtendNode for groups 197 // that are defined inside of "extend" blocks. 198 Extendee *ExtendNode 199 } 200 201 func (*GroupNode) msgElement() {} 202 func (*GroupNode) oneOfElement() {} 203 func (*GroupNode) extendElement() {} 204 205 // NewGroupNode creates a new *GroupNode. The label and options arguments may be 206 // nil but the others must be non-nil. 207 // - label: The token corresponding to the label keyword if present ("optional", 208 // "required", or "repeated"). 209 // - keyword: The token corresponding to the "group" keyword. 210 // - name: The token corresponding to the field's name. 211 // - equals: The token corresponding to the '=' rune after the name. 212 // - tag: The token corresponding to the field's tag number. 213 // - opts: Optional set of field options. 214 // - openBrace: The token corresponding to the "{" rune that starts the body. 215 // - decls: All declarations inside the group body. 216 // - closeBrace: The token corresponding to the "}" rune that ends the body. 217 func NewGroupNode(label *KeywordNode, keyword *KeywordNode, name *IdentNode, equals *RuneNode, tag *UintLiteralNode, opts *CompactOptionsNode, openBrace *RuneNode, decls []MessageElement, closeBrace *RuneNode) *GroupNode { 218 if keyword == nil { 219 panic("fieldType is nil") 220 } 221 if name == nil { 222 panic("name is nil") 223 } 224 if equals == nil { 225 panic("equals is nil") 226 } 227 if tag == nil { 228 panic("tag is nil") 229 } 230 if openBrace == nil { 231 panic("openBrace is nil") 232 } 233 if closeBrace == nil { 234 panic("closeBrace is nil") 235 } 236 numChildren := 6 + len(decls) 237 if label != nil { 238 numChildren++ 239 } 240 if opts != nil { 241 numChildren++ 242 } 243 children := make([]Node, 0, numChildren) 244 if label != nil { 245 children = append(children, label) 246 } 247 children = append(children, keyword, name, equals, tag) 248 if opts != nil { 249 children = append(children, opts) 250 } 251 children = append(children, openBrace) 252 for _, decl := range decls { 253 children = append(children, decl) 254 } 255 children = append(children, closeBrace) 256 257 ret := &GroupNode{ 258 compositeNode: compositeNode{ 259 children: children, 260 }, 261 Label: newFieldLabel(label), 262 Keyword: keyword, 263 Name: name, 264 Equals: equals, 265 Tag: tag, 266 Options: opts, 267 } 268 populateMessageBody(&ret.MessageBody, openBrace, decls, closeBrace) 269 return ret 270 } 271 272 func (n *GroupNode) FieldLabel() Node { 273 if n.Label.KeywordNode == nil { 274 // return nil interface to indicate absence, not a typed nil 275 return nil 276 } 277 return n.Label.KeywordNode 278 } 279 280 func (n *GroupNode) FieldName() Node { 281 return n.Name 282 } 283 284 func (n *GroupNode) FieldType() Node { 285 return n.Keyword 286 } 287 288 func (n *GroupNode) FieldTag() Node { 289 return n.Tag 290 } 291 292 func (n *GroupNode) FieldExtendee() Node { 293 if n.Extendee != nil { 294 return n.Extendee.Extendee 295 } 296 return nil 297 } 298 299 func (n *GroupNode) GetGroupKeyword() Node { 300 return n.Keyword 301 } 302 303 func (n *GroupNode) GetOptions() *CompactOptionsNode { 304 return n.Options 305 } 306 307 func (n *GroupNode) MessageName() Node { 308 return n.Name 309 } 310 311 // OneOfDeclNode is a node in the AST that defines a oneof. There are 312 // multiple types of AST nodes that declare oneofs: 313 // - *OneOfNode 314 // - *SyntheticOneOf 315 // 316 // This also allows NoSourceNode to be used in place of one of the above 317 // for some usages. 318 type OneOfDeclNode interface { 319 Node 320 OneOfName() Node 321 } 322 323 // OneOfNode represents a one-of declaration. Example: 324 // 325 // oneof query { 326 // string by_name = 2; 327 // Type by_type = 3; 328 // Address by_address = 4; 329 // Labels by_label = 5; 330 // } 331 type OneOfNode struct { 332 compositeNode 333 Keyword *KeywordNode 334 Name *IdentNode 335 OpenBrace *RuneNode 336 Decls []OneOfElement 337 CloseBrace *RuneNode 338 } 339 340 func (*OneOfNode) msgElement() {} 341 342 // NewOneOfNode creates a new *OneOfNode. All arguments must be non-nil. While 343 // it is technically allowed for decls to be nil or empty, the resulting node 344 // will not be a valid oneof, which must have at least one field. 345 // - keyword: The token corresponding to the "oneof" keyword. 346 // - name: The token corresponding to the oneof's name. 347 // - openBrace: The token corresponding to the "{" rune that starts the body. 348 // - decls: All declarations inside the oneof body. 349 // - closeBrace: The token corresponding to the "}" rune that ends the body. 350 func NewOneOfNode(keyword *KeywordNode, name *IdentNode, openBrace *RuneNode, decls []OneOfElement, closeBrace *RuneNode) *OneOfNode { 351 if keyword == nil { 352 panic("keyword is nil") 353 } 354 if name == nil { 355 panic("name is nil") 356 } 357 if openBrace == nil { 358 panic("openBrace is nil") 359 } 360 if closeBrace == nil { 361 panic("closeBrace is nil") 362 } 363 children := make([]Node, 0, 4+len(decls)) 364 children = append(children, keyword, name, openBrace) 365 for _, decl := range decls { 366 children = append(children, decl) 367 } 368 children = append(children, closeBrace) 369 370 for _, decl := range decls { 371 switch decl := decl.(type) { 372 case *OptionNode, *FieldNode, *GroupNode, *EmptyDeclNode: 373 default: 374 panic(fmt.Sprintf("invalid OneOfElement type: %T", decl)) 375 } 376 } 377 378 return &OneOfNode{ 379 compositeNode: compositeNode{ 380 children: children, 381 }, 382 Keyword: keyword, 383 Name: name, 384 OpenBrace: openBrace, 385 Decls: decls, 386 CloseBrace: closeBrace, 387 } 388 } 389 390 func (n *OneOfNode) OneOfName() Node { 391 return n.Name 392 } 393 394 // SyntheticOneOf is not an actual node in the AST but a synthetic node 395 // that implements OneOfDeclNode. These are used to represent the implicit 396 // oneof declarations that enclose "proto3 optional" fields. 397 type SyntheticOneOf struct { 398 Field *FieldNode 399 } 400 401 // NewSyntheticOneOf creates a new *SyntheticOneOf that corresponds to the 402 // given proto3 optional field. 403 func NewSyntheticOneOf(field *FieldNode) *SyntheticOneOf { 404 return &SyntheticOneOf{Field: field} 405 } 406 407 func (n *SyntheticOneOf) Start() *SourcePos { 408 return n.Field.Start() 409 } 410 411 func (n *SyntheticOneOf) End() *SourcePos { 412 return n.Field.End() 413 } 414 415 func (n *SyntheticOneOf) LeadingComments() []Comment { 416 return nil 417 } 418 419 func (n *SyntheticOneOf) TrailingComments() []Comment { 420 return nil 421 } 422 423 func (n *SyntheticOneOf) OneOfName() Node { 424 return n.Field.FieldName() 425 } 426 427 // OneOfElement is an interface implemented by all AST nodes that can 428 // appear in the body of a oneof declaration. 429 type OneOfElement interface { 430 Node 431 oneOfElement() 432 } 433 434 var _ OneOfElement = (*OptionNode)(nil) 435 var _ OneOfElement = (*FieldNode)(nil) 436 var _ OneOfElement = (*GroupNode)(nil) 437 var _ OneOfElement = (*EmptyDeclNode)(nil) 438 439 // MapTypeNode represents the type declaration for a map field. It defines 440 // both the key and value types for the map. Example: 441 // 442 // map<string, Values> 443 type MapTypeNode struct { 444 compositeNode 445 Keyword *KeywordNode 446 OpenAngle *RuneNode 447 KeyType *IdentNode 448 Comma *RuneNode 449 ValueType IdentValueNode 450 CloseAngle *RuneNode 451 } 452 453 // NewMapTypeNode creates a new *MapTypeNode. All arguments must be non-nil. 454 // - keyword: The token corresponding to the "map" keyword. 455 // - openAngle: The token corresponding to the "<" rune after the keyword. 456 // - keyType: The token corresponding to the key type for the map. 457 // - comma: The token corresponding to the "," rune between key and value types. 458 // - valType: The token corresponding to the value type for the map. 459 // - closeAngle: The token corresponding to the ">" rune that ends the declaration. 460 func NewMapTypeNode(keyword *KeywordNode, openAngle *RuneNode, keyType *IdentNode, comma *RuneNode, valType IdentValueNode, closeAngle *RuneNode) *MapTypeNode { 461 if keyword == nil { 462 panic("keyword is nil") 463 } 464 if openAngle == nil { 465 panic("openAngle is nil") 466 } 467 if keyType == nil { 468 panic("keyType is nil") 469 } 470 if comma == nil { 471 panic("comma is nil") 472 } 473 if valType == nil { 474 panic("valType is nil") 475 } 476 if closeAngle == nil { 477 panic("closeAngle is nil") 478 } 479 children := []Node{keyword, openAngle, keyType, comma, valType, closeAngle} 480 return &MapTypeNode{ 481 compositeNode: compositeNode{ 482 children: children, 483 }, 484 Keyword: keyword, 485 OpenAngle: openAngle, 486 KeyType: keyType, 487 Comma: comma, 488 ValueType: valType, 489 CloseAngle: closeAngle, 490 } 491 } 492 493 // MapFieldNode represents a map field declaration. Example: 494 // 495 // map<string,string> replacements = 3 [deprecated = true]; 496 type MapFieldNode struct { 497 compositeNode 498 MapType *MapTypeNode 499 Name *IdentNode 500 Equals *RuneNode 501 Tag *UintLiteralNode 502 Options *CompactOptionsNode 503 Semicolon *RuneNode 504 } 505 506 func (*MapFieldNode) msgElement() {} 507 508 // NewMapFieldNode creates a new *MapFieldNode. All arguments must be non-nil 509 // except opts, which may be nil. 510 // - mapType: The token corresponding to the map type. 511 // - name: The token corresponding to the field's name. 512 // - equals: The token corresponding to the '=' rune after the name. 513 // - tag: The token corresponding to the field's tag number. 514 // - opts: Optional set of field options. 515 // - semicolon: The token corresponding to the ";" rune that ends the declaration. 516 func NewMapFieldNode(mapType *MapTypeNode, name *IdentNode, equals *RuneNode, tag *UintLiteralNode, opts *CompactOptionsNode, semicolon *RuneNode) *MapFieldNode { 517 if mapType == nil { 518 panic("mapType is nil") 519 } 520 if name == nil { 521 panic("name is nil") 522 } 523 if equals == nil { 524 panic("equals is nil") 525 } 526 if tag == nil { 527 panic("tag is nil") 528 } 529 if semicolon == nil { 530 panic("semicolon is nil") 531 } 532 numChildren := 5 533 if opts != nil { 534 numChildren++ 535 } 536 children := make([]Node, 0, numChildren) 537 children = append(children, mapType, name, equals, tag) 538 if opts != nil { 539 children = append(children, opts) 540 } 541 children = append(children, semicolon) 542 543 return &MapFieldNode{ 544 compositeNode: compositeNode{ 545 children: children, 546 }, 547 MapType: mapType, 548 Name: name, 549 Equals: equals, 550 Tag: tag, 551 Options: opts, 552 Semicolon: semicolon, 553 } 554 } 555 556 func (n *MapFieldNode) FieldLabel() Node { 557 return nil 558 } 559 560 func (n *MapFieldNode) FieldName() Node { 561 return n.Name 562 } 563 564 func (n *MapFieldNode) FieldType() Node { 565 return n.MapType 566 } 567 568 func (n *MapFieldNode) FieldTag() Node { 569 return n.Tag 570 } 571 572 func (n *MapFieldNode) FieldExtendee() Node { 573 return nil 574 } 575 576 func (n *MapFieldNode) GetGroupKeyword() Node { 577 return nil 578 } 579 580 func (n *MapFieldNode) GetOptions() *CompactOptionsNode { 581 return n.Options 582 } 583 584 func (n *MapFieldNode) MessageName() Node { 585 return n.Name 586 } 587 588 func (n *MapFieldNode) KeyField() *SyntheticMapField { 589 return NewSyntheticMapField(n.MapType.KeyType, 1) 590 } 591 592 func (n *MapFieldNode) ValueField() *SyntheticMapField { 593 return NewSyntheticMapField(n.MapType.ValueType, 2) 594 } 595 596 // SyntheticMapField is not an actual node in the AST but a synthetic node 597 // that implements FieldDeclNode. These are used to represent the implicit 598 // field declarations of the "key" and "value" fields in a map entry. 599 type SyntheticMapField struct { 600 Ident IdentValueNode 601 Tag *UintLiteralNode 602 } 603 604 // NewSyntheticMapField creates a new *SyntheticMapField for the given 605 // identifier (either a key or value type in a map declaration) and tag 606 // number (1 for key, 2 for value). 607 func NewSyntheticMapField(ident IdentValueNode, tagNum uint64) *SyntheticMapField { 608 tag := &UintLiteralNode{ 609 terminalNode: terminalNode{ 610 posRange: PosRange{Start: *ident.Start(), End: *ident.End()}, 611 }, 612 Val: tagNum, 613 } 614 return &SyntheticMapField{Ident: ident, Tag: tag} 615 } 616 617 func (n *SyntheticMapField) Start() *SourcePos { 618 return n.Ident.Start() 619 } 620 621 func (n *SyntheticMapField) End() *SourcePos { 622 return n.Ident.End() 623 } 624 625 func (n *SyntheticMapField) LeadingComments() []Comment { 626 return nil 627 } 628 629 func (n *SyntheticMapField) TrailingComments() []Comment { 630 return nil 631 } 632 633 func (n *SyntheticMapField) FieldLabel() Node { 634 return n.Ident 635 } 636 637 func (n *SyntheticMapField) FieldName() Node { 638 return n.Ident 639 } 640 641 func (n *SyntheticMapField) FieldType() Node { 642 return n.Ident 643 } 644 645 func (n *SyntheticMapField) FieldTag() Node { 646 return n.Tag 647 } 648 649 func (n *SyntheticMapField) FieldExtendee() Node { 650 return nil 651 } 652 653 func (n *SyntheticMapField) GetGroupKeyword() Node { 654 return nil 655 } 656 657 func (n *SyntheticMapField) GetOptions() *CompactOptionsNode { 658 return nil 659 }