github.com/phpstudyer/protoreflect@v1.7.2/desc/protoparse/proto.y (about) 1 %{ 2 package protoparse 3 4 //lint:file-ignore SA4006 generated parser has unused values 5 6 import ( 7 "math" 8 9 "github.com/phpstudyer/protoreflect/desc/protoparse/ast" 10 ) 11 12 %} 13 14 // fields inside this union end up as the fields in a structure known 15 // as ${PREFIX}SymType, of which a reference is passed to the lexer. 16 %union{ 17 file *ast.FileNode 18 syn *ast.SyntaxNode 19 fileDecl ast.FileElement 20 fileDecls []ast.FileElement 21 pkg *ast.PackageNode 22 imprt *ast.ImportNode 23 msg *ast.MessageNode 24 msgDecl ast.MessageElement 25 msgDecls []ast.MessageElement 26 fld *ast.FieldNode 27 mapFld *ast.MapFieldNode 28 mapType *ast.MapTypeNode 29 grp *ast.GroupNode 30 oo *ast.OneOfNode 31 ooDecl ast.OneOfElement 32 ooDecls []ast.OneOfElement 33 ext *ast.ExtensionRangeNode 34 resvd *ast.ReservedNode 35 en *ast.EnumNode 36 enDecl ast.EnumElement 37 enDecls []ast.EnumElement 38 env *ast.EnumValueNode 39 extend *ast.ExtendNode 40 extDecl ast.ExtendElement 41 extDecls []ast.ExtendElement 42 svc *ast.ServiceNode 43 svcDecl ast.ServiceElement 44 svcDecls []ast.ServiceElement 45 mtd *ast.RPCNode 46 rpcType *ast.RPCTypeNode 47 rpcDecl ast.RPCElement 48 rpcDecls []ast.RPCElement 49 opt *ast.OptionNode 50 opts *compactOptionList 51 ref *ast.FieldReferenceNode 52 optNms *fieldRefList 53 cmpctOpts *ast.CompactOptionsNode 54 rng *ast.RangeNode 55 rngs *rangeList 56 names *nameList 57 cid *identList 58 tid ast.IdentValueNode 59 sl *valueList 60 msgField *ast.MessageFieldNode 61 msgEntry *messageFieldEntry 62 msgLit *messageFieldList 63 v ast.ValueNode 64 il ast.IntValueNode 65 str *stringList 66 s *ast.StringLiteralNode 67 i *ast.UintLiteralNode 68 f *ast.FloatLiteralNode 69 id *ast.IdentNode 70 b *ast.RuneNode 71 err error 72 } 73 74 // any non-terminal which returns a value needs a type, which is 75 // really a field name in the above union struct 76 %type <file> file 77 %type <syn> syntax 78 %type <fileDecl> fileDecl 79 %type <fileDecls> fileDecls 80 %type <imprt> import 81 %type <pkg> package 82 %type <opt> option compactOption 83 %type <opts> compactOptionDecls 84 %type <rpcDecl> rpcDecl 85 %type <rpcDecls> rpcDecls 86 %type <ref> optionNameComponent aggName 87 %type <optNms> optionName 88 %type <cmpctOpts> compactOptions 89 %type <v> constant scalarConstant aggregate numLit 90 %type <il> intLit 91 %type <id> name keyType 92 %type <cid> ident 93 %type <tid> typeIdent 94 %type <sl> constantList 95 %type <msgField> aggFieldEntry 96 %type <msgEntry> aggField 97 %type <msgLit> aggFields 98 %type <fld> field oneofField 99 %type <oo> oneof 100 %type <grp> group oneofGroup 101 %type <mapFld> mapField 102 %type <mapType> mapType 103 %type <msg> message 104 %type <msgDecl> messageDecl 105 %type <msgDecls> messageDecls 106 %type <ooDecl> ooDecl 107 %type <ooDecls> ooDecls 108 %type <names> fieldNames 109 %type <resvd> msgReserved enumReserved reservedNames 110 %type <rng> tagRange enumRange 111 %type <rngs> tagRanges enumRanges 112 %type <ext> extensions 113 %type <en> enum 114 %type <enDecl> enumDecl 115 %type <enDecls> enumDecls 116 %type <env> enumValue 117 %type <extend> extend 118 %type <extDecl> extendDecl 119 %type <extDecls> extendDecls 120 %type <str> stringLit 121 %type <svc> service 122 %type <svcDecl> serviceDecl 123 %type <svcDecls> serviceDecls 124 %type <mtd> rpc 125 %type <rpcType> rpcType 126 127 // same for terminals 128 %token <s> _STRING_LIT 129 %token <i> _INT_LIT 130 %token <f> _FLOAT_LIT 131 %token <id> _NAME 132 %token <id> _SYNTAX _IMPORT _WEAK _PUBLIC _PACKAGE _OPTION _TRUE _FALSE _INF _NAN _REPEATED _OPTIONAL _REQUIRED 133 %token <id> _DOUBLE _FLOAT _INT32 _INT64 _UINT32 _UINT64 _SINT32 _SINT64 _FIXED32 _FIXED64 _SFIXED32 _SFIXED64 134 %token <id> _BOOL _STRING _BYTES _GROUP _ONEOF _MAP _EXTENSIONS _TO _MAX _RESERVED _ENUM _MESSAGE _EXTEND 135 %token <id> _SERVICE _RPC _STREAM _RETURNS 136 %token <err> _ERROR 137 // we define all of these, even ones that aren't used, to improve error messages 138 // so it shows the unexpected symbol instead of showing "$unk" 139 %token <b> '=' ';' ':' '{' '}' '\\' '/' '?' '.' ',' '>' '<' '+' '-' '(' ')' '[' ']' '*' '&' '^' '%' '$' '#' '@' '!' '~' '`' 140 141 %% 142 143 file : syntax { 144 $$ = ast.NewFileNode($1, nil) 145 protolex.(*protoLex).res = $$ 146 } 147 | fileDecls { 148 $$ = ast.NewFileNode(nil, $1) 149 protolex.(*protoLex).res = $$ 150 } 151 | syntax fileDecls { 152 $$ = ast.NewFileNode($1, $2) 153 protolex.(*protoLex).res = $$ 154 } 155 | { 156 } 157 158 fileDecls : fileDecls fileDecl { 159 if $2 != nil { 160 $$ = append($1, $2) 161 } else { 162 $$ = $1 163 } 164 } 165 | fileDecl { 166 if $1 != nil { 167 $$ = []ast.FileElement{$1} 168 } else { 169 $$ = nil 170 } 171 } 172 173 fileDecl : import { 174 $$ = $1 175 } 176 | package { 177 $$ = $1 178 } 179 | option { 180 $$ = $1 181 } 182 | message { 183 $$ = $1 184 } 185 | enum { 186 $$ = $1 187 } 188 | extend { 189 $$ = $1 190 } 191 | service { 192 $$ = $1 193 } 194 | ';' { 195 $$ = ast.NewEmptyDeclNode($1) 196 } 197 | error ';' { 198 $$ = nil 199 } 200 | error { 201 $$ = nil 202 } 203 204 syntax : _SYNTAX '=' stringLit ';' { 205 $$ = ast.NewSyntaxNode($1.ToKeyword(), $2, $3.toStringValueNode(), $4) 206 } 207 208 import : _IMPORT stringLit ';' { 209 $$ = ast.NewImportNode($1.ToKeyword(), nil, nil, $2.toStringValueNode(), $3) 210 } 211 | _IMPORT _WEAK stringLit ';' { 212 $$ = ast.NewImportNode($1.ToKeyword(), nil, $2.ToKeyword(), $3.toStringValueNode(), $4) 213 } 214 | _IMPORT _PUBLIC stringLit ';' { 215 $$ = ast.NewImportNode($1.ToKeyword(), $2.ToKeyword(), nil, $3.toStringValueNode(), $4) 216 } 217 218 package : _PACKAGE ident ';' { 219 $$ = ast.NewPackageNode($1.ToKeyword(), $2.toIdentValueNode(nil), $3) 220 } 221 222 ident : name { 223 $$ = &identList{$1, nil, nil} 224 } 225 | name '.' ident { 226 $$ = &identList{$1, $2, $3} 227 } 228 229 option : _OPTION optionName '=' constant ';' { 230 refs, dots := $2.toNodes() 231 optName := ast.NewOptionNameNode(refs, dots) 232 $$ = ast.NewOptionNode($1.ToKeyword(), optName, $3, $4, $5) 233 } 234 235 optionName : optionNameComponent { 236 $$ = &fieldRefList{$1, nil, nil} 237 } 238 | optionNameComponent '.' optionName { 239 $$ = &fieldRefList{$1, $2, $3} 240 } 241 242 optionNameComponent : name { 243 $$ = ast.NewFieldReferenceNode($1) 244 } 245 | '(' typeIdent ')' { 246 $$ = ast.NewExtensionFieldReferenceNode($1, $2, $3) 247 } 248 249 constant : scalarConstant 250 | aggregate 251 252 scalarConstant : stringLit { 253 $$ = $1.toStringValueNode() 254 } 255 | numLit 256 | name { 257 if $1.Val == "true" || $1.Val == "false" { 258 $$ = ast.NewBoolLiteralNode($1.ToKeyword()) 259 } else if $1.Val == "inf" || $1.Val == "nan" { 260 $$ = ast.NewSpecialFloatLiteralNode($1.ToKeyword()) 261 } else { 262 $$ = $1 263 } 264 } 265 266 numLit : _FLOAT_LIT { 267 $$ = $1 268 } 269 | '-' _FLOAT_LIT { 270 $$ = ast.NewSignedFloatLiteralNode($1, $2) 271 } 272 | '+' _FLOAT_LIT { 273 $$ = ast.NewSignedFloatLiteralNode($1, $2) 274 } 275 | '+' _INF { 276 f := ast.NewSpecialFloatLiteralNode($2.ToKeyword()) 277 $$ = ast.NewSignedFloatLiteralNode($1, f) 278 } 279 | '-' _INF { 280 f := ast.NewSpecialFloatLiteralNode($2.ToKeyword()) 281 $$ = ast.NewSignedFloatLiteralNode($1, f) 282 } 283 | _INT_LIT { 284 $$ = $1 285 } 286 | '+' _INT_LIT { 287 $$ = ast.NewPositiveUintLiteralNode($1, $2) 288 } 289 | '-' _INT_LIT { 290 if $2.Val > math.MaxInt64 + 1 { 291 // can't represent as int so treat as float literal 292 $$ = ast.NewSignedFloatLiteralNode($1, $2) 293 } else { 294 $$ = ast.NewNegativeIntLiteralNode($1, $2) 295 } 296 } 297 298 stringLit : _STRING_LIT { 299 $$ = &stringList{$1, nil} 300 } 301 | _STRING_LIT stringLit { 302 $$ = &stringList{$1, $2} 303 } 304 305 aggregate : '{' aggFields '}' { 306 fields, delims := $2.toNodes() 307 $$ = ast.NewMessageLiteralNode($1, fields, delims, $3) 308 } 309 310 aggFields : aggField { 311 if $1 != nil { 312 $$ = &messageFieldList{$1, nil} 313 } else { 314 $$ = nil 315 } 316 } 317 | aggField aggFields { 318 if $1 != nil { 319 $$ = &messageFieldList{$1, $2} 320 } else { 321 $$ = $2 322 } 323 } 324 | { 325 $$ = nil 326 } 327 328 aggField : aggFieldEntry { 329 if $1 != nil { 330 $$ = &messageFieldEntry{$1, nil} 331 } else { 332 $$ = nil 333 } 334 } 335 | aggFieldEntry ',' { 336 if $1 != nil { 337 $$ = &messageFieldEntry{$1, $2} 338 } else { 339 $$ = nil 340 } 341 } 342 | aggFieldEntry ';' { 343 if $1 != nil { 344 $$ = &messageFieldEntry{$1, $2} 345 } else { 346 $$ = nil 347 } 348 } 349 | error ',' { 350 $$ = nil 351 } 352 | error ';' { 353 $$ = nil 354 } 355 | error { 356 $$ = nil 357 } 358 359 aggFieldEntry : aggName ':' scalarConstant { 360 if $1 != nil { 361 $$ = ast.NewMessageFieldNode($1, $2, $3) 362 } else { 363 $$ = nil 364 } 365 } 366 | aggName ':' '[' ']' { 367 if $1 != nil { 368 val := ast.NewArrayLiteralNode($3, nil, nil, $4) 369 $$ = ast.NewMessageFieldNode($1, $2, val) 370 } else { 371 $$ = nil 372 } 373 } 374 | aggName ':' '[' constantList ']' { 375 if $1 != nil { 376 vals, commas := $4.toNodes() 377 val := ast.NewArrayLiteralNode($3, vals, commas, $5) 378 $$ = ast.NewMessageFieldNode($1, $2, val) 379 } else { 380 $$ = nil 381 } 382 } 383 | aggName ':' '[' error ']' { 384 $$ = nil 385 } 386 | aggName ':' aggregate { 387 if $1 != nil { 388 $$ = ast.NewMessageFieldNode($1, $2, $3) 389 } else { 390 $$ = nil 391 } 392 } 393 | aggName aggregate { 394 if $1 != nil { 395 $$ = ast.NewMessageFieldNode($1, nil, $2) 396 } else { 397 $$ = nil 398 } 399 } 400 | aggName ':' '<' aggFields '>' { 401 if $1 != nil { 402 fields, delims := $4.toNodes() 403 msg := ast.NewMessageLiteralNode($3, fields, delims, $5) 404 $$ = ast.NewMessageFieldNode($1, $2, msg) 405 } else { 406 $$ = nil 407 } 408 } 409 | aggName '<' aggFields '>' { 410 if $1 != nil { 411 fields, delims := $3.toNodes() 412 msg := ast.NewMessageLiteralNode($2, fields, delims, $4) 413 $$ = ast.NewMessageFieldNode($1, nil, msg) 414 } else { 415 $$ = nil 416 } 417 } 418 | aggName ':' '<' error '>' { 419 $$ = nil 420 } 421 | aggName '<' error '>' { 422 $$ = nil 423 } 424 425 aggName : name { 426 $$ = ast.NewFieldReferenceNode($1) 427 } 428 | '[' typeIdent ']' { 429 $$ = ast.NewExtensionFieldReferenceNode($1, $2, $3) 430 } 431 | '[' error ']' { 432 $$ = nil 433 } 434 435 constantList : constant { 436 $$ = &valueList{$1, nil, nil} 437 } 438 | constant ',' constantList { 439 $$ = &valueList{$1, $2, $3} 440 } 441 | '<' aggFields '>' { 442 fields, delims := $2.toNodes() 443 msg := ast.NewMessageLiteralNode($1, fields, delims, $3) 444 $$ = &valueList{msg, nil, nil} 445 } 446 | '<' aggFields '>' ',' constantList { 447 fields, delims := $2.toNodes() 448 msg := ast.NewMessageLiteralNode($1, fields, delims, $3) 449 $$ = &valueList{msg, $4, $5} 450 } 451 | '<' error '>' { 452 $$ = nil 453 } 454 | '<' error '>' ',' constantList { 455 $$ = $5 456 } 457 458 typeIdent : ident { 459 $$ = $1.toIdentValueNode(nil) 460 } 461 | '.' ident { 462 $$ = $2.toIdentValueNode($1) 463 } 464 465 field : _REQUIRED typeIdent name '=' _INT_LIT ';' { 466 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6) 467 } 468 | _OPTIONAL typeIdent name '=' _INT_LIT ';' { 469 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6) 470 } 471 | _REPEATED typeIdent name '=' _INT_LIT ';' { 472 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6) 473 } 474 | typeIdent name '=' _INT_LIT ';' { 475 $$ = ast.NewFieldNode(nil, $1, $2, $3, $4, nil, $5) 476 } 477 | _REQUIRED typeIdent name '=' _INT_LIT compactOptions ';' { 478 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7) 479 } 480 | _OPTIONAL typeIdent name '=' _INT_LIT compactOptions ';' { 481 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7) 482 } 483 | _REPEATED typeIdent name '=' _INT_LIT compactOptions ';' { 484 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7) 485 } 486 | typeIdent name '=' _INT_LIT compactOptions ';' { 487 $$ = ast.NewFieldNode(nil, $1, $2, $3, $4, $5, $6) 488 } 489 490 compactOptions: '[' compactOptionDecls ']' { 491 opts, commas := $2.toNodes() 492 $$ = ast.NewCompactOptionsNode($1, opts, commas, $3) 493 } 494 495 compactOptionDecls : compactOption { 496 $$ = &compactOptionList{$1, nil, nil} 497 } 498 | compactOption ',' compactOptionDecls { 499 $$ = &compactOptionList{$1, $2, $3} 500 } 501 502 compactOption: optionName '=' constant { 503 refs, dots := $1.toNodes() 504 optName := ast.NewOptionNameNode(refs, dots) 505 $$ = ast.NewCompactOptionNode(optName, $2, $3) 506 } 507 508 group : _REQUIRED _GROUP name '=' _INT_LIT '{' messageDecls '}' { 509 $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, nil, $6, $7, $8) 510 } 511 | _OPTIONAL _GROUP name '=' _INT_LIT '{' messageDecls '}' { 512 $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, nil, $6, $7, $8) 513 } 514 | _REPEATED _GROUP name '=' _INT_LIT '{' messageDecls '}' { 515 $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, nil, $6, $7, $8) 516 } 517 | _REQUIRED _GROUP name '=' _INT_LIT compactOptions '{' messageDecls '}' { 518 $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, $6, $7, $8, $9) 519 } 520 | _OPTIONAL _GROUP name '=' _INT_LIT compactOptions '{' messageDecls '}' { 521 $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, $6, $7, $8, $9) 522 } 523 | _REPEATED _GROUP name '=' _INT_LIT compactOptions '{' messageDecls '}' { 524 $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, $6, $7, $8, $9) 525 } 526 527 oneof : _ONEOF name '{' ooDecls '}' { 528 $$ = ast.NewOneOfNode($1.ToKeyword(), $2, $3, $4, $5) 529 } 530 531 ooDecls : ooDecls ooDecl { 532 if $2 != nil { 533 $$ = append($1, $2) 534 } else { 535 $$ = $1 536 } 537 } 538 | ooDecl { 539 if $1 != nil { 540 $$ = []ast.OneOfElement{$1} 541 } else { 542 $$ = nil 543 } 544 } 545 | { 546 $$ = nil 547 } 548 549 ooDecl : option { 550 $$ = $1 551 } 552 | oneofField { 553 $$ = $1 554 } 555 | oneofGroup { 556 $$ = $1 557 } 558 | ';' { 559 $$ = ast.NewEmptyDeclNode($1) 560 } 561 | error ';' { 562 $$ = nil 563 } 564 | error { 565 $$ = nil 566 } 567 568 oneofField : typeIdent name '=' _INT_LIT ';' { 569 $$ = ast.NewFieldNode(nil, $1, $2, $3, $4, nil, $5) 570 } 571 | typeIdent name '=' _INT_LIT compactOptions ';' { 572 $$ = ast.NewFieldNode(nil, $1, $2, $3, $4, $5, $6) 573 } 574 575 oneofGroup : _GROUP name '=' _INT_LIT '{' messageDecls '}' { 576 $$ = ast.NewGroupNode(nil, $1.ToKeyword(), $2, $3, $4, nil, $5, $6, $7) 577 } 578 | _GROUP name '=' _INT_LIT compactOptions '{' messageDecls '}' { 579 $$ = ast.NewGroupNode(nil, $1.ToKeyword(), $2, $3, $4, $5, $6, $7, $8) 580 } 581 582 mapField : mapType name '=' _INT_LIT ';' { 583 $$ = ast.NewMapFieldNode($1, $2, $3, $4, nil, $5) 584 } 585 | mapType name '=' _INT_LIT compactOptions ';' { 586 $$ = ast.NewMapFieldNode($1, $2, $3, $4, $5, $6) 587 } 588 589 mapType : _MAP '<' keyType ',' typeIdent '>' { 590 $$ = ast.NewMapTypeNode($1.ToKeyword(), $2, $3, $4, $5, $6) 591 } 592 593 keyType : _INT32 594 | _INT64 595 | _UINT32 596 | _UINT64 597 | _SINT32 598 | _SINT64 599 | _FIXED32 600 | _FIXED64 601 | _SFIXED32 602 | _SFIXED64 603 | _BOOL 604 | _STRING 605 606 extensions : _EXTENSIONS tagRanges ';' { 607 ranges, commas := $2.toNodes() 608 $$ = ast.NewExtensionRangeNode($1.ToKeyword(), ranges, commas, nil, $3) 609 } 610 | _EXTENSIONS tagRanges compactOptions ';' { 611 ranges, commas := $2.toNodes() 612 $$ = ast.NewExtensionRangeNode($1.ToKeyword(), ranges, commas, $3, $4) 613 } 614 615 tagRanges : tagRange { 616 $$ = &rangeList{$1, nil, nil} 617 } 618 | tagRange ',' tagRanges { 619 $$ = &rangeList{$1, $2, $3} 620 } 621 622 tagRange : _INT_LIT { 623 $$ = ast.NewRangeNode($1, nil, nil, nil) 624 } 625 | _INT_LIT _TO _INT_LIT { 626 $$ = ast.NewRangeNode($1, $2.ToKeyword(), $3, nil) 627 } 628 | _INT_LIT _TO _MAX { 629 $$ = ast.NewRangeNode($1, $2.ToKeyword(), nil, $3.ToKeyword()) 630 } 631 632 enumRanges : enumRange { 633 $$ = &rangeList{$1, nil, nil} 634 } 635 | enumRange ',' enumRanges { 636 $$ = &rangeList{$1, $2, $3} 637 } 638 639 enumRange : intLit { 640 $$ = ast.NewRangeNode($1, nil, nil, nil) 641 } 642 | intLit _TO intLit { 643 $$ = ast.NewRangeNode($1, $2.ToKeyword(), $3, nil) 644 } 645 | intLit _TO _MAX { 646 $$ = ast.NewRangeNode($1, $2.ToKeyword(), nil, $3.ToKeyword()) 647 } 648 649 intLit : _INT_LIT { 650 $$ = $1 651 } 652 | '-' _INT_LIT { 653 $$ = ast.NewNegativeIntLiteralNode($1, $2) 654 } 655 656 msgReserved : _RESERVED tagRanges ';' { 657 ranges, commas := $2.toNodes() 658 $$ = ast.NewReservedRangesNode($1.ToKeyword(), ranges, commas, $3) 659 } 660 | reservedNames 661 662 enumReserved : _RESERVED enumRanges ';' { 663 ranges, commas := $2.toNodes() 664 $$ = ast.NewReservedRangesNode($1.ToKeyword(), ranges, commas, $3) 665 } 666 | reservedNames 667 668 reservedNames : _RESERVED fieldNames ';' { 669 names, commas := $2.toNodes() 670 $$ = ast.NewReservedNamesNode($1.ToKeyword(), names, commas, $3) 671 } 672 673 fieldNames : stringLit { 674 $$ = &nameList{$1.toStringValueNode(), nil, nil} 675 } 676 | stringLit ',' fieldNames { 677 $$ = &nameList{$1.toStringValueNode(), $2, $3} 678 } 679 680 enum : _ENUM name '{' enumDecls '}' { 681 $$ = ast.NewEnumNode($1.ToKeyword(), $2, $3, $4, $5) 682 } 683 684 enumDecls : enumDecls enumDecl { 685 if $2 != nil { 686 $$ = append($1, $2) 687 } else { 688 $$ = $1 689 } 690 } 691 | enumDecl { 692 if $1 != nil { 693 $$ = []ast.EnumElement{$1} 694 } else { 695 $$ = nil 696 } 697 } 698 | { 699 $$ = nil 700 } 701 702 enumDecl : option { 703 $$ = $1 704 } 705 | enumValue { 706 $$ = $1 707 } 708 | enumReserved { 709 $$ = $1 710 } 711 | ';' { 712 $$ = ast.NewEmptyDeclNode($1) 713 } 714 | error ';' { 715 $$ = nil 716 } 717 | error { 718 $$ = nil 719 } 720 721 enumValue : name '=' intLit ';' { 722 $$ = ast.NewEnumValueNode($1, $2, $3, nil, $4) 723 } 724 | name '=' intLit compactOptions ';' { 725 $$ = ast.NewEnumValueNode($1, $2, $3, $4, $5) 726 } 727 728 message : _MESSAGE name '{' messageDecls '}' { 729 $$ = ast.NewMessageNode($1.ToKeyword(), $2, $3, $4, $5) 730 } 731 732 messageDecls : messageDecls messageDecl { 733 if $2 != nil { 734 $$ = append($1, $2) 735 } else { 736 $$ = $1 737 } 738 } 739 | messageDecl { 740 if $1 != nil { 741 $$ = []ast.MessageElement{$1} 742 } else { 743 $$ = nil 744 } 745 } 746 | { 747 $$ = nil 748 } 749 750 messageDecl : field { 751 $$ = $1 752 } 753 | enum { 754 $$ = $1 755 } 756 | message { 757 $$ = $1 758 } 759 | extend { 760 $$ = $1 761 } 762 | extensions { 763 $$ = $1 764 } 765 | group { 766 $$ = $1 767 } 768 | option { 769 $$ = $1 770 } 771 | oneof { 772 $$ = $1 773 } 774 | mapField { 775 $$ = $1 776 } 777 | msgReserved { 778 $$ = $1 779 } 780 | ';' { 781 $$ = ast.NewEmptyDeclNode($1) 782 } 783 | error ';' { 784 $$ = nil 785 } 786 | error { 787 $$ = nil 788 } 789 790 extend : _EXTEND typeIdent '{' extendDecls '}' { 791 $$ = ast.NewExtendNode($1.ToKeyword(), $2, $3, $4, $5) 792 } 793 794 extendDecls : extendDecls extendDecl { 795 if $2 != nil { 796 $$ = append($1, $2) 797 } else { 798 $$ = $1 799 } 800 } 801 | extendDecl { 802 if $1 != nil { 803 $$ = []ast.ExtendElement{$1} 804 } else { 805 $$ = nil 806 } 807 } 808 | { 809 $$ = nil 810 } 811 812 extendDecl : field { 813 $$ = $1 814 } 815 | group { 816 $$ = $1 817 } 818 | ';' { 819 $$ = ast.NewEmptyDeclNode($1) 820 } 821 | error ';' { 822 $$ = nil 823 } 824 | error { 825 $$ = nil 826 } 827 828 service : _SERVICE name '{' serviceDecls '}' { 829 $$ = ast.NewServiceNode($1.ToKeyword(), $2, $3, $4, $5) 830 } 831 832 serviceDecls : serviceDecls serviceDecl { 833 if $2 != nil { 834 $$ = append($1, $2) 835 } else { 836 $$ = $1 837 } 838 } 839 | serviceDecl { 840 if $1 != nil { 841 $$ = []ast.ServiceElement{$1} 842 } else { 843 $$ = nil 844 } 845 } 846 | { 847 $$ = nil 848 } 849 850 // NB: doc suggests support for "stream" declaration, separate from "rpc", but 851 // it does not appear to be supported in protoc (doc is likely from grammar for 852 // Google-internal version of protoc, with support for streaming stubby) 853 serviceDecl : option { 854 $$ = $1 855 } 856 | rpc { 857 $$ = $1 858 } 859 | ';' { 860 $$ = ast.NewEmptyDeclNode($1) 861 } 862 | error ';' { 863 $$ = nil 864 } 865 | error { 866 $$ = nil 867 } 868 869 rpc : _RPC name rpcType _RETURNS rpcType ';' { 870 $$ = ast.NewRPCNode($1.ToKeyword(), $2, $3, $4.ToKeyword(), $5, $6) 871 } 872 | _RPC name rpcType _RETURNS rpcType '{' rpcDecls '}' { 873 $$ = ast.NewRPCNodeWithBody($1.ToKeyword(), $2, $3, $4.ToKeyword(), $5, $6, $7, $8) 874 } 875 876 rpcType : '(' _STREAM typeIdent ')' { 877 $$ = ast.NewRPCTypeNode($1, $2.ToKeyword(), $3, $4) 878 } 879 | '(' typeIdent ')' { 880 $$ = ast.NewRPCTypeNode($1, nil, $2, $3) 881 } 882 883 rpcDecls : rpcDecls rpcDecl { 884 if $2 != nil { 885 $$ = append($1, $2) 886 } else { 887 $$ = $1 888 } 889 } 890 | rpcDecl { 891 if $1 != nil { 892 $$ = []ast.RPCElement{$1} 893 } else { 894 $$ = nil 895 } 896 } 897 | { 898 $$ = nil 899 } 900 901 rpcDecl : option { 902 $$ = $1 903 } 904 | ';' { 905 $$ = ast.NewEmptyDeclNode($1) 906 } 907 | error ';' { 908 $$ = nil 909 } 910 | error { 911 $$ = nil 912 } 913 914 name : _NAME 915 | _SYNTAX 916 | _IMPORT 917 | _WEAK 918 | _PUBLIC 919 | _PACKAGE 920 | _OPTION 921 | _TRUE 922 | _FALSE 923 | _INF 924 | _NAN 925 | _REPEATED 926 | _OPTIONAL 927 | _REQUIRED 928 | _DOUBLE 929 | _FLOAT 930 | _INT32 931 | _INT64 932 | _UINT32 933 | _UINT64 934 | _SINT32 935 | _SINT64 936 | _FIXED32 937 | _FIXED64 938 | _SFIXED32 939 | _SFIXED64 940 | _BOOL 941 | _STRING 942 | _BYTES 943 | _GROUP 944 | _ONEOF 945 | _MAP 946 | _EXTENSIONS 947 | _TO 948 | _MAX 949 | _RESERVED 950 | _ENUM 951 | _MESSAGE 952 | _EXTEND 953 | _SERVICE 954 | _RPC 955 | _STREAM 956 | _RETURNS 957 958 %%