github.com/bakjos/protoreflect@v1.9.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/bakjos/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 msgElementName extElementName oneofElementName enumElementName
    92  %type <cid>       ident msgElementIdent extElementIdent oneofElementIdent
    93  %type <tid>       typeIdent msgElementTypeIdent extElementTypeIdent oneofElementTypeIdent
    94  %type <sl>        constantList
    95  %type <msgField>  aggFieldEntry
    96  %type <msgEntry>  aggField
    97  %type <msgLit>    aggFields
    98  %type <fld>       oneofField msgField extField
    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  // to mimic limitations of protoc recursive-descent parser,
   230  // we don't allowed message statement keywords as identifiers
   231  // (or oneof statement keywords [e.g. "option"] below)
   232  
   233  msgElementIdent : msgElementName {
   234  		$$ = &identList{$1, nil, nil}
   235  	}
   236  	| msgElementName '.' ident {
   237  		$$ = &identList{$1, $2, $3}
   238  	}
   239  
   240  extElementIdent : extElementName {
   241  		$$ = &identList{$1, nil, nil}
   242  	}
   243  	| extElementName '.' ident {
   244  		$$ = &identList{$1, $2, $3}
   245  	}
   246  
   247  oneofElementIdent : oneofElementName {
   248  		$$ = &identList{$1, nil, nil}
   249  	}
   250  	| oneofElementName '.' ident {
   251  		$$ = &identList{$1, $2, $3}
   252  	}
   253  
   254  option : _OPTION optionName '=' constant ';' {
   255  		refs, dots := $2.toNodes()
   256  		optName := ast.NewOptionNameNode(refs, dots)
   257  		$$ = ast.NewOptionNode($1.ToKeyword(), optName, $3, $4, $5)
   258  	}
   259  
   260  optionName : optionNameComponent {
   261  		$$ = &fieldRefList{$1, nil, nil}
   262  	}
   263  	| optionNameComponent '.' optionName {
   264  		$$ = &fieldRefList{$1, $2, $3}
   265  	}
   266  
   267  optionNameComponent : name {
   268  		$$ = ast.NewFieldReferenceNode($1)
   269  	}
   270  	| '(' typeIdent ')' {
   271  		$$ = ast.NewExtensionFieldReferenceNode($1, $2, $3)
   272  	}
   273  
   274  constant : scalarConstant
   275  	| aggregate
   276  
   277  scalarConstant : stringLit {
   278  		$$ = $1.toStringValueNode()
   279  	}
   280  	| numLit
   281  	| name {
   282  		if $1.Val == "true" || $1.Val == "false" {
   283  			$$ = ast.NewBoolLiteralNode($1.ToKeyword())
   284  		} else if $1.Val == "inf" || $1.Val == "nan" {
   285  			$$ = ast.NewSpecialFloatLiteralNode($1.ToKeyword())
   286  		} else {
   287  			$$ = $1
   288  		}
   289  	}
   290  
   291  numLit : _FLOAT_LIT {
   292  		$$ = $1
   293  	}
   294  	| '-' _FLOAT_LIT {
   295  		$$ = ast.NewSignedFloatLiteralNode($1, $2)
   296  	}
   297  	| '+' _FLOAT_LIT {
   298  		$$ = ast.NewSignedFloatLiteralNode($1, $2)
   299  	}
   300  	| '+' _INF {
   301  		f := ast.NewSpecialFloatLiteralNode($2.ToKeyword())
   302  		$$ = ast.NewSignedFloatLiteralNode($1, f)
   303  	}
   304  	| '-' _INF {
   305  		f := ast.NewSpecialFloatLiteralNode($2.ToKeyword())
   306  		$$ = ast.NewSignedFloatLiteralNode($1, f)
   307  	}
   308  	| _INT_LIT {
   309  		$$ = $1
   310  	}
   311  	| '+' _INT_LIT {
   312  		$$ = ast.NewPositiveUintLiteralNode($1, $2)
   313  	}
   314  	| '-' _INT_LIT {
   315  		if $2.Val > math.MaxInt64 + 1 {
   316  			// can't represent as int so treat as float literal
   317  			$$ = ast.NewSignedFloatLiteralNode($1, $2)
   318  		} else {
   319  			$$ = ast.NewNegativeIntLiteralNode($1, $2)
   320  		}
   321  	}
   322  
   323  stringLit : _STRING_LIT {
   324  		$$ = &stringList{$1, nil}
   325  	}
   326  	| _STRING_LIT stringLit  {
   327  		$$ = &stringList{$1, $2}
   328  	}
   329  
   330  aggregate : '{' aggFields '}' {
   331  		fields, delims := $2.toNodes()
   332  		$$ = ast.NewMessageLiteralNode($1, fields, delims, $3)
   333  	}
   334  
   335  aggFields : aggField {
   336  		if $1 != nil {
   337  			$$ = &messageFieldList{$1, nil}
   338  		} else {
   339  			$$ = nil
   340  		}
   341  	}
   342  	| aggField aggFields {
   343  		if $1 != nil {
   344  			$$ = &messageFieldList{$1, $2}
   345  		} else {
   346  			$$ = $2
   347  		}
   348  	}
   349  	| {
   350  		$$ = nil
   351  	}
   352  
   353  aggField : aggFieldEntry {
   354  		if $1 != nil {
   355  			$$ = &messageFieldEntry{$1, nil}
   356  		} else {
   357  			$$ = nil
   358  		}
   359  	}
   360  	| aggFieldEntry ',' {
   361  		if $1 != nil {
   362  			$$ = &messageFieldEntry{$1, $2}
   363  		} else {
   364  			$$ = nil
   365  		}
   366  	}
   367  	| aggFieldEntry ';' {
   368  		if $1 != nil {
   369  			$$ = &messageFieldEntry{$1, $2}
   370  		} else {
   371  			$$ = nil
   372  		}
   373  	}
   374  	| error ',' {
   375  		$$ = nil
   376  	}
   377  	| error ';' {
   378  		$$ = nil
   379  	}
   380  	| error {
   381  		$$ = nil
   382  	}
   383  
   384  aggFieldEntry : aggName ':' scalarConstant {
   385  		if $1 != nil {
   386  			$$ = ast.NewMessageFieldNode($1, $2, $3)
   387  		} else {
   388  			$$ = nil
   389  		}
   390  	}
   391  	| aggName ':' '[' ']' {
   392  		if $1 != nil {
   393  			val := ast.NewArrayLiteralNode($3, nil, nil, $4)
   394  			$$ = ast.NewMessageFieldNode($1, $2, val)
   395  		} else {
   396  			$$ = nil
   397  		}
   398  	}
   399  	| aggName ':' '[' constantList ']' {
   400  		if $1 != nil {
   401  			vals, commas := $4.toNodes()
   402  			val := ast.NewArrayLiteralNode($3, vals, commas, $5)
   403  			$$ = ast.NewMessageFieldNode($1, $2, val)
   404  		} else {
   405  			$$ = nil
   406  		}
   407  	}
   408  	| aggName ':' '[' error ']' {
   409  		$$ = nil
   410  	}
   411  	| aggName ':' aggregate {
   412  		if $1 != nil {
   413  			$$ = ast.NewMessageFieldNode($1, $2, $3)
   414  		} else {
   415  			$$ = nil
   416  		}
   417  	}
   418  	| aggName aggregate {
   419  		if $1 != nil {
   420  			$$ = ast.NewMessageFieldNode($1, nil, $2)
   421  		} else {
   422  			$$ = nil
   423  		}
   424  	}
   425  	| aggName ':' '<' aggFields '>' {
   426  		if $1 != nil {
   427  			fields, delims := $4.toNodes()
   428  			msg := ast.NewMessageLiteralNode($3, fields, delims, $5)
   429  			$$ = ast.NewMessageFieldNode($1, $2, msg)
   430  		} else {
   431  			$$ = nil
   432  		}
   433  	}
   434  	| aggName '<' aggFields '>' {
   435  		if $1 != nil {
   436  			fields, delims := $3.toNodes()
   437  			msg := ast.NewMessageLiteralNode($2, fields, delims, $4)
   438  			$$ = ast.NewMessageFieldNode($1, nil, msg)
   439  		} else {
   440  			$$ = nil
   441  		}
   442  	}
   443  	| aggName ':' '<' error '>' {
   444  		$$ = nil
   445  	}
   446  	| aggName '<' error '>' {
   447  		$$ = nil
   448  	}
   449  
   450  aggName : name {
   451  		$$ = ast.NewFieldReferenceNode($1)
   452  	}
   453  	| '[' typeIdent ']' {
   454  		$$ = ast.NewExtensionFieldReferenceNode($1, $2, $3)
   455  	}
   456  	| '[' error ']' {
   457  		$$ = nil
   458  	}
   459  
   460  constantList : constant {
   461  		$$ = &valueList{$1, nil, nil}
   462  	}
   463  	| constant ',' constantList {
   464  		$$ = &valueList{$1, $2, $3}
   465  	}
   466  	| '<' aggFields '>' {
   467  		fields, delims := $2.toNodes()
   468  		msg := ast.NewMessageLiteralNode($1, fields, delims, $3)
   469  		$$ = &valueList{msg, nil, nil}
   470  	}
   471  	| '<' aggFields '>' ',' constantList {
   472  		fields, delims := $2.toNodes()
   473  		msg := ast.NewMessageLiteralNode($1, fields, delims, $3)
   474  		$$ = &valueList{msg, $4, $5}
   475  	}
   476  	| '<' error '>' {
   477  		$$ = nil
   478  	}
   479  	| '<' error '>' ',' constantList {
   480  		$$ = $5
   481  	}
   482  
   483  typeIdent : ident {
   484  		$$ = $1.toIdentValueNode(nil)
   485  	}
   486  	| '.' ident {
   487  		$$ = $2.toIdentValueNode($1)
   488  	}
   489  
   490  msgElementTypeIdent : msgElementIdent {
   491  		$$ = $1.toIdentValueNode(nil)
   492  	}
   493  	| '.' ident {
   494  		$$ = $2.toIdentValueNode($1)
   495  	}
   496  
   497  extElementTypeIdent : extElementIdent {
   498  		$$ = $1.toIdentValueNode(nil)
   499  	}
   500  	| '.' ident {
   501  		$$ = $2.toIdentValueNode($1)
   502  	}
   503  
   504  oneofElementTypeIdent : oneofElementIdent {
   505  		$$ = $1.toIdentValueNode(nil)
   506  	}
   507  	| '.' ident {
   508  		$$ = $2.toIdentValueNode($1)
   509  	}
   510  
   511  msgField : _REQUIRED typeIdent name '=' _INT_LIT ';' {
   512  		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6)
   513  	}
   514  	| _OPTIONAL typeIdent name '=' _INT_LIT ';' {
   515  		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6)
   516  	}
   517  	| _REPEATED typeIdent name '=' _INT_LIT ';' {
   518  		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6)
   519  	}
   520  	| _REQUIRED typeIdent name '=' _INT_LIT compactOptions ';' {
   521  		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7)
   522  	}
   523  	| _OPTIONAL typeIdent name '=' _INT_LIT compactOptions ';' {
   524  		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7)
   525  	}
   526  	| _REPEATED typeIdent name '=' _INT_LIT compactOptions ';' {
   527  		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7)
   528  	}
   529  	| msgElementTypeIdent name '=' _INT_LIT ';' {
   530  		$$ = ast.NewFieldNode(nil, $1, $2, $3, $4, nil, $5)
   531  	}
   532  	| msgElementTypeIdent name '=' _INT_LIT compactOptions ';' {
   533  		$$ = ast.NewFieldNode(nil, $1, $2, $3, $4, $5, $6)
   534  	}
   535  
   536  extField : _REQUIRED typeIdent name '=' _INT_LIT ';' {
   537  		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6)
   538  	}
   539  	| _OPTIONAL typeIdent name '=' _INT_LIT ';' {
   540  		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6)
   541  	}
   542  	| _REPEATED typeIdent name '=' _INT_LIT ';' {
   543  		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6)
   544  	}
   545  	| _REQUIRED typeIdent name '=' _INT_LIT compactOptions ';' {
   546  		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7)
   547  	}
   548  	| _OPTIONAL typeIdent name '=' _INT_LIT compactOptions ';' {
   549  		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7)
   550  	}
   551  	| _REPEATED typeIdent name '=' _INT_LIT compactOptions ';' {
   552  		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7)
   553  	}
   554  	| extElementTypeIdent name '=' _INT_LIT ';' {
   555  		$$ = ast.NewFieldNode(nil, $1, $2, $3, $4, nil, $5)
   556  	}
   557  	| extElementTypeIdent name '=' _INT_LIT compactOptions ';' {
   558  		$$ = ast.NewFieldNode(nil, $1, $2, $3, $4, $5, $6)
   559  	}
   560  
   561  compactOptions: '[' compactOptionDecls ']' {
   562  		opts, commas := $2.toNodes()
   563  		$$ = ast.NewCompactOptionsNode($1, opts, commas, $3)
   564  	}
   565  
   566  compactOptionDecls : compactOption {
   567  		$$ = &compactOptionList{$1, nil, nil}
   568  	}
   569  	| compactOption ',' compactOptionDecls {
   570  		$$ = &compactOptionList{$1, $2, $3}
   571  	}
   572  
   573  compactOption: optionName '=' constant {
   574  		refs, dots := $1.toNodes()
   575  		optName := ast.NewOptionNameNode(refs, dots)
   576  		$$ = ast.NewCompactOptionNode(optName, $2, $3)
   577  	}
   578  
   579  group : _REQUIRED _GROUP name '=' _INT_LIT '{' messageDecls '}' {
   580  		$$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, nil, $6, $7, $8)
   581  	}
   582  	| _OPTIONAL _GROUP name '=' _INT_LIT '{' messageDecls '}' {
   583  		$$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, nil, $6, $7, $8)
   584  	}
   585  	| _REPEATED _GROUP name '=' _INT_LIT '{' messageDecls '}' {
   586  		$$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, nil, $6, $7, $8)
   587  	}
   588  	| _REQUIRED _GROUP name '=' _INT_LIT compactOptions '{' messageDecls '}' {
   589  		$$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, $6, $7, $8, $9)
   590  	}
   591  	| _OPTIONAL _GROUP name '=' _INT_LIT compactOptions '{' messageDecls '}' {
   592  		$$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, $6, $7, $8, $9)
   593  	}
   594  	| _REPEATED _GROUP name '=' _INT_LIT compactOptions '{' messageDecls '}' {
   595  		$$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, $6, $7, $8, $9)
   596  	}
   597  
   598  oneof : _ONEOF name '{' ooDecls '}' {
   599  		$$ = ast.NewOneOfNode($1.ToKeyword(), $2, $3, $4, $5)
   600  	}
   601  
   602  ooDecls : ooDecls ooDecl {
   603  		if $2 != nil {
   604  			$$ = append($1, $2)
   605  		} else {
   606  			$$ = $1
   607  		}
   608  	}
   609  	| ooDecl {
   610  		if $1 != nil {
   611  			$$ = []ast.OneOfElement{$1}
   612  		} else {
   613  			$$ = nil
   614  		}
   615  	}
   616  	| {
   617  		$$ = nil
   618  	}
   619  
   620  ooDecl : option {
   621  		$$ = $1
   622  	}
   623  	| oneofField {
   624  		$$ = $1
   625  	}
   626  	| oneofGroup {
   627  		$$ = $1
   628  	}
   629  	| ';' {
   630  		$$ = ast.NewEmptyDeclNode($1)
   631  	}
   632  	| error ';' {
   633  		$$ = nil
   634  	}
   635  	| error {
   636  		$$ = nil
   637  	}
   638  
   639  oneofField : oneofElementTypeIdent name '=' _INT_LIT ';' {
   640  		$$ = ast.NewFieldNode(nil, $1, $2, $3, $4, nil, $5)
   641  	}
   642  	| oneofElementTypeIdent name '=' _INT_LIT compactOptions ';' {
   643  		$$ = ast.NewFieldNode(nil, $1, $2, $3, $4, $5, $6)
   644  	}
   645  
   646  oneofGroup : _GROUP name '=' _INT_LIT '{' messageDecls '}' {
   647  		$$ = ast.NewGroupNode(nil, $1.ToKeyword(), $2, $3, $4, nil, $5, $6, $7)
   648  	}
   649  	| _GROUP name '=' _INT_LIT compactOptions '{' messageDecls '}' {
   650  		$$ = ast.NewGroupNode(nil, $1.ToKeyword(), $2, $3, $4, $5, $6, $7, $8)
   651  	}
   652  
   653  mapField : mapType name '=' _INT_LIT ';' {
   654  		$$ = ast.NewMapFieldNode($1, $2, $3, $4, nil, $5)
   655  	}
   656  	| mapType name '=' _INT_LIT compactOptions ';' {
   657  		$$ = ast.NewMapFieldNode($1, $2, $3, $4, $5, $6)
   658  	}
   659  
   660  mapType : _MAP '<' keyType ',' typeIdent '>' {
   661  		$$ = ast.NewMapTypeNode($1.ToKeyword(), $2, $3, $4, $5, $6)
   662  	}
   663  
   664  keyType : _INT32
   665  	| _INT64
   666  	| _UINT32
   667  	| _UINT64
   668  	| _SINT32
   669  	| _SINT64
   670  	| _FIXED32
   671  	| _FIXED64
   672  	| _SFIXED32
   673  	| _SFIXED64
   674  	| _BOOL
   675  	| _STRING
   676  
   677  extensions : _EXTENSIONS tagRanges ';' {
   678  		ranges, commas := $2.toNodes()
   679  		$$ = ast.NewExtensionRangeNode($1.ToKeyword(), ranges, commas, nil, $3)
   680  	}
   681  	| _EXTENSIONS tagRanges compactOptions ';' {
   682  		ranges, commas := $2.toNodes()
   683  		$$ = ast.NewExtensionRangeNode($1.ToKeyword(), ranges, commas, $3, $4)
   684  	}
   685  
   686  tagRanges : tagRange {
   687  		$$ = &rangeList{$1, nil, nil}
   688  	}
   689  	| tagRange ',' tagRanges {
   690  		$$ = &rangeList{$1, $2, $3}
   691  	}
   692  
   693  tagRange : _INT_LIT {
   694  		$$ = ast.NewRangeNode($1, nil, nil, nil)
   695  	}
   696  	| _INT_LIT _TO _INT_LIT {
   697  		$$ = ast.NewRangeNode($1, $2.ToKeyword(), $3, nil)
   698  	}
   699  	| _INT_LIT _TO _MAX {
   700  		$$ = ast.NewRangeNode($1, $2.ToKeyword(), nil, $3.ToKeyword())
   701  	}
   702  
   703  enumRanges : enumRange {
   704  		$$ = &rangeList{$1, nil, nil}
   705  	}
   706  	| enumRange ',' enumRanges {
   707  		$$ = &rangeList{$1, $2, $3}
   708  	}
   709  
   710  enumRange : intLit {
   711  		$$ = ast.NewRangeNode($1, nil, nil, nil)
   712  	}
   713  	| intLit _TO intLit {
   714  		$$ = ast.NewRangeNode($1, $2.ToKeyword(), $3, nil)
   715  	}
   716  	| intLit _TO _MAX {
   717  		$$ = ast.NewRangeNode($1, $2.ToKeyword(), nil, $3.ToKeyword())
   718  	}
   719  
   720  intLit : _INT_LIT {
   721  		$$ = $1
   722  	}
   723  	| '-' _INT_LIT {
   724  		$$ = ast.NewNegativeIntLiteralNode($1, $2)
   725  	}
   726  
   727  msgReserved : _RESERVED tagRanges ';' {
   728  		ranges, commas := $2.toNodes()
   729  		$$ = ast.NewReservedRangesNode($1.ToKeyword(), ranges, commas, $3)
   730  	}
   731  	| reservedNames
   732  
   733  enumReserved : _RESERVED enumRanges ';' {
   734  		ranges, commas := $2.toNodes()
   735  		$$ = ast.NewReservedRangesNode($1.ToKeyword(), ranges, commas, $3)
   736  	}
   737  	| reservedNames
   738  
   739  reservedNames : _RESERVED fieldNames ';' {
   740  		names, commas := $2.toNodes()
   741  		$$ = ast.NewReservedNamesNode($1.ToKeyword(), names, commas, $3)
   742  	}
   743  
   744  fieldNames : stringLit {
   745  		$$ = &nameList{$1.toStringValueNode(), nil, nil}
   746  	}
   747  	| stringLit ',' fieldNames {
   748  		$$ = &nameList{$1.toStringValueNode(), $2, $3}
   749  	}
   750  
   751  enum : _ENUM name '{' enumDecls '}' {
   752  		$$ = ast.NewEnumNode($1.ToKeyword(), $2, $3, $4, $5)
   753  	}
   754  
   755  enumDecls : enumDecls enumDecl {
   756  		if $2 != nil {
   757  			$$ = append($1, $2)
   758  		} else {
   759  			$$ = $1
   760  		}
   761  	}
   762  	| enumDecl {
   763  		if $1 != nil {
   764  			$$ = []ast.EnumElement{$1}
   765  		} else {
   766  			$$ = nil
   767  		}
   768  	}
   769  	| {
   770  		$$ = nil
   771  	}
   772  
   773  enumDecl : option {
   774  		$$ = $1
   775  	}
   776  	| enumValue {
   777  		$$ = $1
   778  	}
   779  	| enumReserved {
   780  		$$ = $1
   781  	}
   782  	| ';' {
   783  		$$ = ast.NewEmptyDeclNode($1)
   784  	}
   785  	| error ';' {
   786  		$$ = nil
   787  	}
   788  	| error {
   789  		$$ = nil
   790  	}
   791  
   792  enumValue : enumElementName '=' intLit ';' {
   793  		$$ = ast.NewEnumValueNode($1, $2, $3, nil, $4)
   794  	}
   795  	|  enumElementName '=' intLit compactOptions ';' {
   796  		$$ = ast.NewEnumValueNode($1, $2, $3, $4, $5)
   797  	}
   798  
   799  message : _MESSAGE name '{' messageDecls '}' {
   800  		$$ = ast.NewMessageNode($1.ToKeyword(), $2, $3, $4, $5)
   801  	}
   802  
   803  messageDecls : messageDecls messageDecl {
   804  		if $2 != nil {
   805  			$$ = append($1, $2)
   806  		} else {
   807  			$$ = $1
   808  		}
   809  	}
   810  	| messageDecl {
   811  		if $1 != nil {
   812  			$$ = []ast.MessageElement{$1}
   813  		} else {
   814  			$$ = nil
   815  		}
   816  	}
   817  	| {
   818  		$$ = nil
   819  	}
   820  
   821  messageDecl : msgField {
   822  		$$ = $1
   823  	}
   824  	| enum {
   825  		$$ = $1
   826  	}
   827  	| message {
   828  		$$ = $1
   829  	}
   830  	| extend {
   831  		$$ = $1
   832  	}
   833  	| extensions {
   834  		$$ = $1
   835  	}
   836  	| group {
   837  		$$ = $1
   838  	}
   839  	| option {
   840  		$$ = $1
   841  	}
   842  	| oneof {
   843  		$$ = $1
   844  	}
   845  	| mapField {
   846  		$$ = $1
   847  	}
   848  	| msgReserved {
   849  		$$ = $1
   850  	}
   851  	| ';' {
   852  		$$ = ast.NewEmptyDeclNode($1)
   853  	}
   854  	| error ';' {
   855  		$$ = nil
   856  	}
   857  	| error {
   858  		$$ = nil
   859  	}
   860  
   861  extend : _EXTEND typeIdent '{' extendDecls '}' {
   862  		$$ = ast.NewExtendNode($1.ToKeyword(), $2, $3, $4, $5)
   863  	}
   864  
   865  extendDecls : extendDecls extendDecl {
   866  		if $2 != nil {
   867  			$$ = append($1, $2)
   868  		} else {
   869  			$$ = $1
   870  		}
   871  	}
   872  	| extendDecl {
   873  		if $1 != nil {
   874  			$$ = []ast.ExtendElement{$1}
   875  		} else {
   876  			$$ = nil
   877  		}
   878  	}
   879  	| {
   880  		$$ = nil
   881  	}
   882  
   883  extendDecl : extField {
   884  		$$ = $1
   885  	}
   886  	| group {
   887  		$$ = $1
   888  	}
   889  	| ';' {
   890  		$$ = ast.NewEmptyDeclNode($1)
   891  	}
   892  	| error ';' {
   893  		$$ = nil
   894  	}
   895  	| error {
   896  		$$ = nil
   897  	}
   898  
   899  service : _SERVICE name '{' serviceDecls '}' {
   900  		$$ = ast.NewServiceNode($1.ToKeyword(), $2, $3, $4, $5)
   901  	}
   902  
   903  serviceDecls : serviceDecls serviceDecl {
   904  		if $2 != nil {
   905  			$$ = append($1, $2)
   906  		} else {
   907  			$$ = $1
   908  		}
   909  	}
   910  	| serviceDecl {
   911  		if $1 != nil {
   912  			$$ = []ast.ServiceElement{$1}
   913  		} else {
   914  			$$ = nil
   915  		}
   916  	}
   917  	| {
   918  		$$ = nil
   919  	}
   920  
   921  // NB: doc suggests support for "stream" declaration, separate from "rpc", but
   922  // it does not appear to be supported in protoc (doc is likely from grammar for
   923  // Google-internal version of protoc, with support for streaming stubby)
   924  serviceDecl : option {
   925  		$$ = $1
   926  	}
   927  	| rpc {
   928  		$$ = $1
   929  	}
   930  	| ';' {
   931  		$$ = ast.NewEmptyDeclNode($1)
   932  	}
   933  	| error ';' {
   934  		$$ = nil
   935  	}
   936  	| error {
   937  		$$ = nil
   938  	}
   939  
   940  rpc : _RPC name rpcType _RETURNS rpcType ';' {
   941  		$$ = ast.NewRPCNode($1.ToKeyword(), $2, $3, $4.ToKeyword(), $5, $6)
   942  	}
   943  	| _RPC name rpcType _RETURNS rpcType '{' rpcDecls '}' {
   944  		$$ = ast.NewRPCNodeWithBody($1.ToKeyword(), $2, $3, $4.ToKeyword(), $5, $6, $7, $8)
   945  	}
   946  
   947  rpcType : '(' _STREAM typeIdent ')' {
   948  		$$ = ast.NewRPCTypeNode($1, $2.ToKeyword(), $3, $4)
   949  	}
   950  	| '(' typeIdent ')' {
   951  		$$ = ast.NewRPCTypeNode($1, nil, $2, $3)
   952  	}
   953  
   954  rpcDecls : rpcDecls rpcDecl {
   955  		if $2 != nil {
   956  			$$ = append($1, $2)
   957  		} else {
   958  			$$ = $1
   959  		}
   960  	}
   961  	| rpcDecl {
   962  		if $1 != nil {
   963  			$$ = []ast.RPCElement{$1}
   964  		} else {
   965  			$$ = nil
   966  		}
   967  	}
   968  	| {
   969  		$$ = nil
   970  	}
   971  
   972  rpcDecl : option {
   973  		$$ = $1
   974  	}
   975  	| ';' {
   976  		$$ = ast.NewEmptyDeclNode($1)
   977  	}
   978  	| error ';' {
   979  		$$ = nil
   980  	}
   981  	| error {
   982  		$$ = nil
   983  	}
   984  
   985  // excludes message, enum, oneof, extensions, reserved, extend,
   986  //   option, optional, required, and repeated
   987  msgElementName : _NAME
   988  	| _SYNTAX
   989  	| _IMPORT
   990  	| _WEAK
   991  	| _PUBLIC
   992  	| _PACKAGE
   993  	| _TRUE
   994  	| _FALSE
   995  	| _INF
   996  	| _NAN
   997  	| _DOUBLE
   998  	| _FLOAT
   999  	| _INT32
  1000  	| _INT64
  1001  	| _UINT32
  1002  	| _UINT64
  1003  	| _SINT32
  1004  	| _SINT64
  1005  	| _FIXED32
  1006  	| _FIXED64
  1007  	| _SFIXED32
  1008  	| _SFIXED64
  1009  	| _BOOL
  1010  	| _STRING
  1011  	| _BYTES
  1012  	| _GROUP
  1013  	| _MAP
  1014  	| _TO
  1015  	| _MAX
  1016  	| _SERVICE
  1017  	| _RPC
  1018  	| _STREAM
  1019  	| _RETURNS
  1020  
  1021  // excludes optional, required, and repeated
  1022  extElementName : _NAME
  1023  	| _SYNTAX
  1024  	| _IMPORT
  1025  	| _WEAK
  1026  	| _PUBLIC
  1027  	| _PACKAGE
  1028  	| _OPTION
  1029  	| _TRUE
  1030  	| _FALSE
  1031  	| _INF
  1032  	| _NAN
  1033  	| _DOUBLE
  1034  	| _FLOAT
  1035  	| _INT32
  1036  	| _INT64
  1037  	| _UINT32
  1038  	| _UINT64
  1039  	| _SINT32
  1040  	| _SINT64
  1041  	| _FIXED32
  1042  	| _FIXED64
  1043  	| _SFIXED32
  1044  	| _SFIXED64
  1045  	| _BOOL
  1046  	| _STRING
  1047  	| _BYTES
  1048  	| _GROUP
  1049  	| _ONEOF
  1050  	| _MAP
  1051  	| _EXTENSIONS
  1052  	| _TO
  1053  	| _MAX
  1054  	| _RESERVED
  1055  	| _ENUM
  1056  	| _MESSAGE
  1057  	| _EXTEND
  1058  	| _SERVICE
  1059  	| _RPC
  1060  	| _STREAM
  1061  	| _RETURNS
  1062  
  1063  // excludes reserved, option
  1064  enumElementName : _NAME
  1065  	| _SYNTAX
  1066  	| _IMPORT
  1067  	| _WEAK
  1068  	| _PUBLIC
  1069  	| _PACKAGE
  1070  	| _TRUE
  1071  	| _FALSE
  1072  	| _INF
  1073  	| _NAN
  1074  	| _REPEATED
  1075  	| _OPTIONAL
  1076  	| _REQUIRED
  1077  	| _DOUBLE
  1078  	| _FLOAT
  1079  	| _INT32
  1080  	| _INT64
  1081  	| _UINT32
  1082  	| _UINT64
  1083  	| _SINT32
  1084  	| _SINT64
  1085  	| _FIXED32
  1086  	| _FIXED64
  1087  	| _SFIXED32
  1088  	| _SFIXED64
  1089  	| _BOOL
  1090  	| _STRING
  1091  	| _BYTES
  1092  	| _GROUP
  1093  	| _ONEOF
  1094  	| _MAP
  1095  	| _EXTENSIONS
  1096  	| _TO
  1097  	| _MAX
  1098  	| _ENUM
  1099  	| _MESSAGE
  1100  	| _EXTEND
  1101  	| _SERVICE
  1102  	| _RPC
  1103  	| _STREAM
  1104  	| _RETURNS
  1105  
  1106  // excludes option, optional, required, and repeated
  1107  oneofElementName : _NAME
  1108  	| _SYNTAX
  1109  	| _IMPORT
  1110  	| _WEAK
  1111  	| _PUBLIC
  1112  	| _PACKAGE
  1113  	| _TRUE
  1114  	| _FALSE
  1115  	| _INF
  1116  	| _NAN
  1117  	| _DOUBLE
  1118  	| _FLOAT
  1119  	| _INT32
  1120  	| _INT64
  1121  	| _UINT32
  1122  	| _UINT64
  1123  	| _SINT32
  1124  	| _SINT64
  1125  	| _FIXED32
  1126  	| _FIXED64
  1127  	| _SFIXED32
  1128  	| _SFIXED64
  1129  	| _BOOL
  1130  	| _STRING
  1131  	| _BYTES
  1132  	| _GROUP
  1133  	| _ONEOF
  1134  	| _MAP
  1135  	| _EXTENSIONS
  1136  	| _TO
  1137  	| _MAX
  1138  	| _RESERVED
  1139  	| _ENUM
  1140  	| _MESSAGE
  1141  	| _EXTEND
  1142  	| _SERVICE
  1143  	| _RPC
  1144  	| _STREAM
  1145  	| _RETURNS
  1146  
  1147  name : _NAME
  1148  	| _SYNTAX
  1149  	| _IMPORT
  1150  	| _WEAK
  1151  	| _PUBLIC
  1152  	| _PACKAGE
  1153  	| _OPTION
  1154  	| _TRUE
  1155  	| _FALSE
  1156  	| _INF
  1157  	| _NAN
  1158  	| _REPEATED
  1159  	| _OPTIONAL
  1160  	| _REQUIRED
  1161  	| _DOUBLE
  1162  	| _FLOAT
  1163  	| _INT32
  1164  	| _INT64
  1165  	| _UINT32
  1166  	| _UINT64
  1167  	| _SINT32
  1168  	| _SINT64
  1169  	| _FIXED32
  1170  	| _FIXED64
  1171  	| _SFIXED32
  1172  	| _SFIXED64
  1173  	| _BOOL
  1174  	| _STRING
  1175  	| _BYTES
  1176  	| _GROUP
  1177  	| _ONEOF
  1178  	| _MAP
  1179  	| _EXTENSIONS
  1180  	| _TO
  1181  	| _MAX
  1182  	| _RESERVED
  1183  	| _ENUM
  1184  	| _MESSAGE
  1185  	| _EXTEND
  1186  	| _SERVICE
  1187  	| _RPC
  1188  	| _STREAM
  1189  	| _RETURNS
  1190  
  1191  %%