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  %%