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