Repository: jhump/protoreflect
Pull request #383 (2021-02-10 02:49:16)

mirror protoc's recursive descent parser limitations
Towards the goal of more perfect parity between protoparse and protoc: This disallows certain keywords in certain contexts so that protoparse will now reject some proto sources that it previously accepted but that were rejected by protoc.

This should address the underlying issue described in https://github.com/bufbuild/buf/issues/225.




Patch:
diff --git a/desc/protoparse/proto.y b/desc/protoparse/proto.y
index c4d4993..63b32d9 100644
--- a/desc/protoparse/proto.y
+++ b/desc/protoparse/proto.y
@@ -88,14 +88,14 @@ import (
 %type <cmpctOpts> compactOptions
 %type <v>         constant scalarConstant aggregate numLit
 %type <il>        intLit
-%type <id>        name keyType
-%type <cid>       ident
-%type <tid>       typeIdent
+%type <id>        name keyType msgElementName extElementName oneofElementName enumElementName
+%type <cid>       ident msgElementIdent extElementIdent oneofElementIdent
+%type <tid>       typeIdent msgElementTypeIdent extElementTypeIdent oneofElementTypeIdent
 %type <sl>        constantList
 %type <msgField>  aggFieldEntry
 %type <msgEntry>  aggField
 %type <msgLit>    aggFields
-%type <fld>       field oneofField
+%type <fld>       oneofField msgField extField
 %type <oo>        oneof
 %type <grp>       group oneofGroup
 %type <mapFld>    mapField
@@ -156,18 +156,18 @@ file : syntax {
 	}
 
 fileDecls : fileDecls fileDecl {
-        if $2 != nil {
-    		$$ = append($1, $2)
-        } else {
-            $$ = $1
-        }
+		if $2 != nil {
+			$$ = append($1, $2)
+		} else {
+			$$ = $1
+		}
 	}
 	| fileDecl {
-	    if $1 != nil {
-	        $$ = []ast.FileElement{$1}
-        } else {
-            $$ = nil
-        }
+		if $1 != nil {
+			$$ = []ast.FileElement{$1}
+		} else {
+			$$ = nil
+		}
 	}
 
 fileDecl : import {
@@ -195,10 +195,10 @@ fileDecl : import {
 		$$ = ast.NewEmptyDeclNode($1)
 	}
 	| error ';' {
-	    $$ = nil
+		$$ = nil
 	}
 	| error {
-	    $$ = nil
+		$$ = nil
 	}
 
 syntax : _SYNTAX '=' stringLit ';' {
@@ -220,23 +220,48 @@ package : _PACKAGE ident ';' {
 	}
 
 ident : name {
-        $$ = &identList{$1, nil, nil}
-    }
+		$$ = &identList{$1, nil, nil}
+	}
 	| name '.' ident {
-        $$ = &identList{$1, $2, $3}
+		$$ = &identList{$1, $2, $3}
+	}
+
+// to mimic limitations of protoc recursive-descent parser,
+// we don't allowed message statement keywords as identifiers
+// (or oneof statement keywords [e.g. "option"] below)
+
+msgElementIdent : msgElementName {
+		$$ = &identList{$1, nil, nil}
+	}
+	| msgElementName '.' ident {
+		$$ = &identList{$1, $2, $3}
+	}
+
+extElementIdent : extElementName {
+		$$ = &identList{$1, nil, nil}
+	}
+	| extElementName '.' ident {
+		$$ = &identList{$1, $2, $3}
+	}
+
+oneofElementIdent : oneofElementName {
+		$$ = &identList{$1, nil, nil}
+	}
+	| oneofElementName '.' ident {
+		$$ = &identList{$1, $2, $3}
 	}
 
 option : _OPTION optionName '=' constant ';' {
-        refs, dots := $2.toNodes()
-        optName := ast.NewOptionNameNode(refs, dots)
-        $$ = ast.NewOptionNode($1.ToKeyword(), optName, $3, $4, $5)
+		refs, dots := $2.toNodes()
+		optName := ast.NewOptionNameNode(refs, dots)
+		$$ = ast.NewOptionNode($1.ToKeyword(), optName, $3, $4, $5)
 	}
 
 optionName : optionNameComponent {
-        $$ = &fieldRefList{$1, nil, nil}
-    }
-    | optionNameComponent '.' optionName {
-        $$ = &fieldRefList{$1, $2, $3}
+		$$ = &fieldRefList{$1, nil, nil}
+	}
+	| optionNameComponent '.' optionName {
+		$$ = &fieldRefList{$1, $2, $3}
 	}
 
 optionNameComponent : name {
@@ -264,8 +289,8 @@ scalarConstant : stringLit {
 	}
 
 numLit : _FLOAT_LIT {
-        $$ = $1
-    }
+		$$ = $1
+	}
 	| '-' _FLOAT_LIT {
 		$$ = ast.NewSignedFloatLiteralNode($1, $2)
 	}
@@ -273,274 +298,320 @@ numLit : _FLOAT_LIT {
 		$$ = ast.NewSignedFloatLiteralNode($1, $2)
 	}
 	| '+' _INF {
-	    f := ast.NewSpecialFloatLiteralNode($2.ToKeyword())
+		f := ast.NewSpecialFloatLiteralNode($2.ToKeyword())
 		$$ = ast.NewSignedFloatLiteralNode($1, f)
 	}
 	| '-' _INF {
-	    f := ast.NewSpecialFloatLiteralNode($2.ToKeyword())
+		f := ast.NewSpecialFloatLiteralNode($2.ToKeyword())
 		$$ = ast.NewSignedFloatLiteralNode($1, f)
 	}
 	| _INT_LIT {
-        $$ = $1
-    }
-    | '+' _INT_LIT {
-        $$ = ast.NewPositiveUintLiteralNode($1, $2)
-    }
-    | '-' _INT_LIT {
-        if $2.Val > math.MaxInt64 + 1 {
-            // can't represent as int so treat as float literal
-            $$ = ast.NewSignedFloatLiteralNode($1, $2)
-        } else {
-            $$ = ast.NewNegativeIntLiteralNode($1, $2)
-        }
-    }
+		$$ = $1
+	}
+	| '+' _INT_LIT {
+		$$ = ast.NewPositiveUintLiteralNode($1, $2)
+	}
+	| '-' _INT_LIT {
+		if $2.Val > math.MaxInt64 + 1 {
+			// can't represent as int so treat as float literal
+			$$ = ast.NewSignedFloatLiteralNode($1, $2)
+		} else {
+			$$ = ast.NewNegativeIntLiteralNode($1, $2)
+		}
+	}
 
 stringLit : _STRING_LIT {
-        $$ = &stringList{$1, nil}
-    }
-    | _STRING_LIT stringLit  {
-        $$ = &stringList{$1, $2}
-    }
+		$$ = &stringList{$1, nil}
+	}
+	| _STRING_LIT stringLit  {
+		$$ = &stringList{$1, $2}
+	}
 
 aggregate : '{' aggFields '}' {
-        fields, delims := $2.toNodes()
-        $$ = ast.NewMessageLiteralNode($1, fields, delims, $3)
+		fields, delims := $2.toNodes()
+		$$ = ast.NewMessageLiteralNode($1, fields, delims, $3)
 	}
 
 aggFields : aggField {
-	    if $1 != nil {
-	        $$ = &messageFieldList{$1, nil}
-        } else {
-            $$ = nil
-        }
-    }
+		if $1 != nil {
+			$$ = &messageFieldList{$1, nil}
+		} else {
+			$$ = nil
+		}
+	}
 	| aggField aggFields {
-        if $1 != nil {
-            $$ = &messageFieldList{$1, $2}
-        } else {
-            $$ = $2
-        }
+		if $1 != nil {
+			$$ = &messageFieldList{$1, $2}
+		} else {
+			$$ = $2
+		}
 	}
 	| {
 		$$ = nil
 	}
 
 aggField : aggFieldEntry {
-        if $1 != nil {
-            $$ = &messageFieldEntry{$1, nil}
-        } else {
-            $$ = nil
-        }
-    }
+		if $1 != nil {
+			$$ = &messageFieldEntry{$1, nil}
+		} else {
+			$$ = nil
+		}
+	}
 	| aggFieldEntry ',' {
-	    if $1 != nil {
-    		$$ = &messageFieldEntry{$1, $2}
-        } else {
-            $$ = nil
-        }
+		if $1 != nil {
+			$$ = &messageFieldEntry{$1, $2}
+		} else {
+			$$ = nil
+		}
 	}
 	| aggFieldEntry ';' {
-	    if $1 != nil {
-    		$$ = &messageFieldEntry{$1, $2}
-        } else {
-            $$ = nil
-        }
+		if $1 != nil {
+			$$ = &messageFieldEntry{$1, $2}
+		} else {
+			$$ = nil
+		}
 	}
 	| error ',' {
-	    $$ = nil
+		$$ = nil
 	}
 	| error ';' {
-	    $$ = nil
+		$$ = nil
 	}
 	| error {
-	    $$ = nil
+		$$ = nil
 	}
 
 aggFieldEntry : aggName ':' scalarConstant {
-        if $1 != nil {
-            $$ = ast.NewMessageFieldNode($1, $2, $3)
-        } else {
-            $$ = nil
-        }
+		if $1 != nil {
+			$$ = ast.NewMessageFieldNode($1, $2, $3)
+		} else {
+			$$ = nil
+		}
 	}
 	| aggName ':' '[' ']' {
-	    if $1 != nil {
-            val := ast.NewArrayLiteralNode($3, nil, nil, $4)
-            $$ = ast.NewMessageFieldNode($1, $2, val)
-	    } else {
-	        $$ = nil
-	    }
+		if $1 != nil {
+			val := ast.NewArrayLiteralNode($3, nil, nil, $4)
+			$$ = ast.NewMessageFieldNode($1, $2, val)
+		} else {
+			$$ = nil
+		}
 	}
 	| aggName ':' '[' constantList ']' {
-	    if $1 != nil {
-            vals, commas := $4.toNodes()
-            val := ast.NewArrayLiteralNode($3, vals, commas, $5)
-            $$ = ast.NewMessageFieldNode($1, $2, val)
-	    } else {
-	        $$ = nil
-	    }
+		if $1 != nil {
+			vals, commas := $4.toNodes()
+			val := ast.NewArrayLiteralNode($3, vals, commas, $5)
+			$$ = ast.NewMessageFieldNode($1, $2, val)
+		} else {
+			$$ = nil
+		}
 	}
 	| aggName ':' '[' error ']' {
-	    $$ = nil
+		$$ = nil
 	}
 	| aggName ':' aggregate {
-	    if $1 != nil {
-            $$ = ast.NewMessageFieldNode($1, $2, $3)
-	    } else {
-	        $$ = nil
-	    }
+		if $1 != nil {
+			$$ = ast.NewMessageFieldNode($1, $2, $3)
+		} else {
+			$$ = nil
+		}
 	}
 	| aggName aggregate {
-        if $1 != nil {
-            $$ = ast.NewMessageFieldNode($1, nil, $2)
-        } else {
-            $$ = nil
-        }
+		if $1 != nil {
+			$$ = ast.NewMessageFieldNode($1, nil, $2)
+		} else {
+			$$ = nil
+		}
 	}
 	| aggName ':' '<' aggFields '>' {
-	    if $1 != nil {
-            fields, delims := $4.toNodes()
-            msg := ast.NewMessageLiteralNode($3, fields, delims, $5)
-            $$ = ast.NewMessageFieldNode($1, $2, msg)
-        } else {
-            $$ = nil
-        }
+		if $1 != nil {
+			fields, delims := $4.toNodes()
+			msg := ast.NewMessageLiteralNode($3, fields, delims, $5)
+			$$ = ast.NewMessageFieldNode($1, $2, msg)
+		} else {
+			$$ = nil
+		}
 	}
 	| aggName '<' aggFields '>' {
-	    if $1 != nil {
-            fields, delims := $3.toNodes()
-            msg := ast.NewMessageLiteralNode($2, fields, delims, $4)
-            $$ = ast.NewMessageFieldNode($1, nil, msg)
-        } else {
-            $$ = nil
-        }
+		if $1 != nil {
+			fields, delims := $3.toNodes()
+			msg := ast.NewMessageLiteralNode($2, fields, delims, $4)
+			$$ = ast.NewMessageFieldNode($1, nil, msg)
+		} else {
+			$$ = nil
+		}
 	}
 	| aggName ':' '<' error '>' {
-	    $$ = nil
+		$$ = nil
 	}
 	| aggName '<' error '>' {
-	    $$ = nil
+		$$ = nil
 	}
 
 aggName : name {
-        $$ = ast.NewFieldReferenceNode($1)
+		$$ = ast.NewFieldReferenceNode($1)
 	}
 	| '[' typeIdent ']' {
-        $$ = ast.NewExtensionFieldReferenceNode($1, $2, $3)
+		$$ = ast.NewExtensionFieldReferenceNode($1, $2, $3)
 	}
 	| '[' error ']' {
-	    $$ = nil
+		$$ = nil
 	}
 
 constantList : constant {
-        $$ = &valueList{$1, nil, nil}
+		$$ = &valueList{$1, nil, nil}
 	}
 	| constant ',' constantList {
-        $$ = &valueList{$1, $2, $3}
+		$$ = &valueList{$1, $2, $3}
 	}
 	| '<' aggFields '>' {
-        fields, delims := $2.toNodes()
-        msg := ast.NewMessageLiteralNode($1, fields, delims, $3)
-        $$ = &valueList{msg, nil, nil}
+		fields, delims := $2.toNodes()
+		msg := ast.NewMessageLiteralNode($1, fields, delims, $3)
+		$$ = &valueList{msg, nil, nil}
 	}
 	| '<' aggFields '>' ',' constantList {
-        fields, delims := $2.toNodes()
-        msg := ast.NewMessageLiteralNode($1, fields, delims, $3)
-        $$ = &valueList{msg, $4, $5}
+		fields, delims := $2.toNodes()
+		msg := ast.NewMessageLiteralNode($1, fields, delims, $3)
+		$$ = &valueList{msg, $4, $5}
 	}
 	| '<' error '>' {
-	    $$ = nil
+		$$ = nil
 	}
 	| '<' error '>' ',' constantList {
-	    $$ = $5
+		$$ = $5
 	}
 
 typeIdent : ident {
-        $$ = $1.toIdentValueNode(nil)
-    }
-    | '.' ident {
-        $$ = $2.toIdentValueNode($1)
-    }
+		$$ = $1.toIdentValueNode(nil)
+	}
+	| '.' ident {
+		$$ = $2.toIdentValueNode($1)
+	}
+
+msgElementTypeIdent : msgElementIdent {
+		$$ = $1.toIdentValueNode(nil)
+	}
+	| '.' ident {
+		$$ = $2.toIdentValueNode($1)
+	}
+
+extElementTypeIdent : extElementIdent {
+		$$ = $1.toIdentValueNode(nil)
+	}
+	| '.' ident {
+		$$ = $2.toIdentValueNode($1)
+	}
 
-field : _REQUIRED typeIdent name '=' _INT_LIT ';' {
-        $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6)
+oneofElementTypeIdent : oneofElementIdent {
+		$$ = $1.toIdentValueNode(nil)
+	}
+	| '.' ident {
+		$$ = $2.toIdentValueNode($1)
+	}
+
+msgField : _REQUIRED typeIdent name '=' _INT_LIT ';' {
+		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6)
 	}
 	| _OPTIONAL typeIdent name '=' _INT_LIT ';' {
-        $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6)
+		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6)
 	}
 	| _REPEATED typeIdent name '=' _INT_LIT ';' {
-        $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6)
+		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6)
+	}
+	| _REQUIRED typeIdent name '=' _INT_LIT compactOptions ';' {
+		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7)
+	}
+	| _OPTIONAL typeIdent name '=' _INT_LIT compactOptions ';' {
+		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7)
+	}
+	| _REPEATED typeIdent name '=' _INT_LIT compactOptions ';' {
+		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7)
+	}
+	| msgElementTypeIdent name '=' _INT_LIT ';' {
+		$$ = ast.NewFieldNode(nil, $1, $2, $3, $4, nil, $5)
 	}
-	| typeIdent name '=' _INT_LIT ';' {
-        $$ = ast.NewFieldNode(nil, $1, $2, $3, $4, nil, $5)
+	| msgElementTypeIdent name '=' _INT_LIT compactOptions ';' {
+		$$ = ast.NewFieldNode(nil, $1, $2, $3, $4, $5, $6)
+	}
+
+extField : _REQUIRED typeIdent name '=' _INT_LIT ';' {
+		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6)
+	}
+	| _OPTIONAL typeIdent name '=' _INT_LIT ';' {
+		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6)
+	}
+	| _REPEATED typeIdent name '=' _INT_LIT ';' {
+		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6)
 	}
 	| _REQUIRED typeIdent name '=' _INT_LIT compactOptions ';' {
-        $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7)
+		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7)
 	}
 	| _OPTIONAL typeIdent name '=' _INT_LIT compactOptions ';' {
-        $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7)
+		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7)
 	}
 	| _REPEATED typeIdent name '=' _INT_LIT compactOptions ';' {
-        $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7)
+		$$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7)
+	}
+	| extElementTypeIdent name '=' _INT_LIT ';' {
+		$$ = ast.NewFieldNode(nil, $1, $2, $3, $4, nil, $5)
 	}
-	| typeIdent name '=' _INT_LIT compactOptions ';' {
-        $$ = ast.NewFieldNode(nil, $1, $2, $3, $4, $5, $6)
+	| extElementTypeIdent name '=' _INT_LIT compactOptions ';' {
+		$$ = ast.NewFieldNode(nil, $1, $2, $3, $4, $5, $6)
 	}
 
 compactOptions: '[' compactOptionDecls ']' {
-        opts, commas := $2.toNodes()
-        $$ = ast.NewCompactOptionsNode($1, opts, commas, $3)
-    }
+		opts, commas := $2.toNodes()
+		$$ = ast.NewCompactOptionsNode($1, opts, commas, $3)
+	}
 
 compactOptionDecls : compactOption {
-        $$ = &compactOptionList{$1, nil, nil}
-    }
-    | compactOption ',' compactOptionDecls {
-        $$ = &compactOptionList{$1, $2, $3}
+		$$ = &compactOptionList{$1, nil, nil}
+	}
+	| compactOption ',' compactOptionDecls {
+		$$ = &compactOptionList{$1, $2, $3}
 	}
 
 compactOption: optionName '=' constant {
-        refs, dots := $1.toNodes()
-        optName := ast.NewOptionNameNode(refs, dots)
-        $$ = ast.NewCompactOptionNode(optName, $2, $3)
+		refs, dots := $1.toNodes()
+		optName := ast.NewOptionNameNode(refs, dots)
+		$$ = ast.NewCompactOptionNode(optName, $2, $3)
 	}
 
 group : _REQUIRED _GROUP name '=' _INT_LIT '{' messageDecls '}' {
-        $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, nil, $6, $7, $8)
+		$$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, nil, $6, $7, $8)
 	}
 	| _OPTIONAL _GROUP name '=' _INT_LIT '{' messageDecls '}' {
-        $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, nil, $6, $7, $8)
+		$$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, nil, $6, $7, $8)
 	}
 	| _REPEATED _GROUP name '=' _INT_LIT '{' messageDecls '}' {
-        $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, nil, $6, $7, $8)
+		$$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, nil, $6, $7, $8)
 	}
 	| _REQUIRED _GROUP name '=' _INT_LIT compactOptions '{' messageDecls '}' {
-        $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, $6, $7, $8, $9)
+		$$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, $6, $7, $8, $9)
 	}
 	| _OPTIONAL _GROUP name '=' _INT_LIT compactOptions '{' messageDecls '}' {
-        $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, $6, $7, $8, $9)
+		$$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, $6, $7, $8, $9)
 	}
 	| _REPEATED _GROUP name '=' _INT_LIT compactOptions '{' messageDecls '}' {
-        $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, $6, $7, $8, $9)
+		$$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, $6, $7, $8, $9)
 	}
 
 oneof : _ONEOF name '{' ooDecls '}' {
-        $$ = ast.NewOneOfNode($1.ToKeyword(), $2, $3, $4, $5)
+		$$ = ast.NewOneOfNode($1.ToKeyword(), $2, $3, $4, $5)
 	}
 
 ooDecls : ooDecls ooDecl {
-        if $2 != nil {
-    		$$ = append($1, $2)
-        } else {
-            $$ = $1
-        }
+		if $2 != nil {
+			$$ = append($1, $2)
+		} else {
+			$$ = $1
+		}
 	}
 	| ooDecl {
-	    if $1 != nil {
-	        $$ = []ast.OneOfElement{$1}
-        } else {
-            $$ = nil
-        }
+		if $1 != nil {
+			$$ = []ast.OneOfElement{$1}
+		} else {
+			$$ = nil
+		}
 	}
 	| {
 		$$ = nil
@@ -556,39 +627,39 @@ ooDecl : option {
 		$$ = $1
 	}
 	| ';' {
-	    $$ = ast.NewEmptyDeclNode($1)
+		$$ = ast.NewEmptyDeclNode($1)
 	}
 	| error ';' {
-	    $$ = nil
+		$$ = nil
 	}
 	| error {
-	    $$ = nil
+		$$ = nil
 	}
 
-oneofField : typeIdent name '=' _INT_LIT ';' {
-        $$ = ast.NewFieldNode(nil, $1, $2, $3, $4, nil, $5)
+oneofField : oneofElementTypeIdent name '=' _INT_LIT ';' {
+		$$ = ast.NewFieldNode(nil, $1, $2, $3, $4, nil, $5)
 	}
-	| typeIdent name '=' _INT_LIT compactOptions ';' {
-        $$ = ast.NewFieldNode(nil, $1, $2, $3, $4, $5, $6)
+	| oneofElementTypeIdent name '=' _INT_LIT compactOptions ';' {
+		$$ = ast.NewFieldNode(nil, $1, $2, $3, $4, $5, $6)
 	}
 
 oneofGroup : _GROUP name '=' _INT_LIT '{' messageDecls '}' {
-        $$ = ast.NewGroupNode(nil, $1.ToKeyword(), $2, $3, $4, nil, $5, $6, $7)
+		$$ = ast.NewGroupNode(nil, $1.ToKeyword(), $2, $3, $4, nil, $5, $6, $7)
 	}
 	| _GROUP name '=' _INT_LIT compactOptions '{' messageDecls '}' {
-        $$ = ast.NewGroupNode(nil, $1.ToKeyword(), $2, $3, $4, $5, $6, $7, $8)
+		$$ = ast.NewGroupNode(nil, $1.ToKeyword(), $2, $3, $4, $5, $6, $7, $8)
 	}
 
 mapField : mapType name '=' _INT_LIT ';' {
-        $$ = ast.NewMapFieldNode($1, $2, $3, $4, nil, $5)
+		$$ = ast.NewMapFieldNode($1, $2, $3, $4, nil, $5)
 	}
 	| mapType name '=' _INT_LIT compactOptions ';' {
-        $$ = ast.NewMapFieldNode($1, $2, $3, $4, $5, $6)
+		$$ = ast.NewMapFieldNode($1, $2, $3, $4, $5, $6)
 	}
 
 mapType : _MAP '<' keyType ',' typeIdent '>' {
-        $$ = ast.NewMapTypeNode($1.ToKeyword(), $2, $3, $4, $5, $6)
-    }
+		$$ = ast.NewMapTypeNode($1.ToKeyword(), $2, $3, $4, $5, $6)
+	}
 
 keyType : _INT32
 	| _INT64
@@ -604,96 +675,96 @@ keyType : _INT32
 	| _STRING
 
 extensions : _EXTENSIONS tagRanges ';' {
-        ranges, commas := $2.toNodes()
-        $$ = ast.NewExtensionRangeNode($1.ToKeyword(), ranges, commas, nil, $3)
+		ranges, commas := $2.toNodes()
+		$$ = ast.NewExtensionRangeNode($1.ToKeyword(), ranges, commas, nil, $3)
 	}
 	| _EXTENSIONS tagRanges compactOptions ';' {
-        ranges, commas := $2.toNodes()
-        $$ = ast.NewExtensionRangeNode($1.ToKeyword(), ranges, commas, $3, $4)
+		ranges, commas := $2.toNodes()
+		$$ = ast.NewExtensionRangeNode($1.ToKeyword(), ranges, commas, $3, $4)
 	}
 
 tagRanges : tagRange {
 		$$ = &rangeList{$1, nil, nil}
-    }
-    | tagRange ',' tagRanges {
+	}
+	| tagRange ',' tagRanges {
 		$$ = &rangeList{$1, $2, $3}
 	}
 
 tagRange : _INT_LIT {
-        $$ = ast.NewRangeNode($1, nil, nil, nil)
+		$$ = ast.NewRangeNode($1, nil, nil, nil)
 	}
 	| _INT_LIT _TO _INT_LIT {
-        $$ = ast.NewRangeNode($1, $2.ToKeyword(), $3, nil)
+		$$ = ast.NewRangeNode($1, $2.ToKeyword(), $3, nil)
 	}
 	| _INT_LIT _TO _MAX {
-        $$ = ast.NewRangeNode($1, $2.ToKeyword(), nil, $3.ToKeyword())
+		$$ = ast.NewRangeNode($1, $2.ToKeyword(), nil, $3.ToKeyword())
 	}
 
 enumRanges : enumRange {
 		$$ = &rangeList{$1, nil, nil}
-    }
-    | enumRange ',' enumRanges {
+	}
+	| enumRange ',' enumRanges {
 		$$ = &rangeList{$1, $2, $3}
 	}
 
 enumRange : intLit {
-        $$ = ast.NewRangeNode($1, nil, nil, nil)
+		$$ = ast.NewRangeNode($1, nil, nil, nil)
 	}
 	| intLit _TO intLit {
-        $$ = ast.NewRangeNode($1, $2.ToKeyword(), $3, nil)
+		$$ = ast.NewRangeNode($1, $2.ToKeyword(), $3, nil)
 	}
 	| intLit _TO _MAX {
-        $$ = ast.NewRangeNode($1, $2.ToKeyword(), nil, $3.ToKeyword())
+		$$ = ast.NewRangeNode($1, $2.ToKeyword(), nil, $3.ToKeyword())
 	}
 
 intLit : _INT_LIT {
-        $$ = $1
+		$$ = $1
 	}
 	| '-' _INT_LIT {
-	    $$ = ast.NewNegativeIntLiteralNode($1, $2)
+		$$ = ast.NewNegativeIntLiteralNode($1, $2)
 	}
 
 msgReserved : _RESERVED tagRanges ';' {
-        ranges, commas := $2.toNodes()
-        $$ = ast.NewReservedRangesNode($1.ToKeyword(), ranges, commas, $3)
+		ranges, commas := $2.toNodes()
+		$$ = ast.NewReservedRangesNode($1.ToKeyword(), ranges, commas, $3)
 	}
 	| reservedNames
 
 enumReserved : _RESERVED enumRanges ';' {
-        ranges, commas := $2.toNodes()
-        $$ = ast.NewReservedRangesNode($1.ToKeyword(), ranges, commas, $3)
+		ranges, commas := $2.toNodes()
+		$$ = ast.NewReservedRangesNode($1.ToKeyword(), ranges, commas, $3)
 	}
 	| reservedNames
 
 reservedNames : _RESERVED fieldNames ';' {
-        names, commas := $2.toNodes()
-        $$ = ast.NewReservedNamesNode($1.ToKeyword(), names, commas, $3)
+		names, commas := $2.toNodes()
+		$$ = ast.NewReservedNamesNode($1.ToKeyword(), names, commas, $3)
 	}
 
 fieldNames : stringLit {
-        $$ = &nameList{$1.toStringValueNode(), nil, nil}
-    }
-    | stringLit ',' fieldNames {
-        $$ = &nameList{$1.toStringValueNode(), $2, $3}
-    }
+		$$ = &nameList{$1.toStringValueNode(), nil, nil}
+	}
+	| stringLit ',' fieldNames {
+		$$ = &nameList{$1.toStringValueNode(), $2, $3}
+	}
 
 enum : _ENUM name '{' enumDecls '}' {
-        $$ = ast.NewEnumNode($1.ToKeyword(), $2, $3, $4, $5)
+		$$ = ast.NewEnumNode($1.ToKeyword(), $2, $3, $4, $5)
 	}
 
 enumDecls : enumDecls enumDecl {
-        if $2 != nil {
-    		$$ = append($1, $2)
-        } else {
-            $$ = $1
-        }
+		if $2 != nil {
+			$$ = append($1, $2)
+		} else {
+			$$ = $1
+		}
 	}
 	| enumDecl {
-	    if $1 != nil {
-    	    $$ = []ast.EnumElement{$1}
-	    } else {
-	        $$ = nil
-	    }
+		if $1 != nil {
+			$$ = []ast.EnumElement{$1}
+		} else {
+			$$ = nil
+		}
 	}
 	| {
 		$$ = nil
@@ -709,45 +780,45 @@ enumDecl : option {
 		$$ = $1
 	}
 	| ';' {
-	    $$ = ast.NewEmptyDeclNode($1)
+		$$ = ast.NewEmptyDeclNode($1)
 	}
 	| error ';' {
-	    $$ = nil
+		$$ = nil
 	}
 	| error {
-	    $$ = nil
+		$$ = nil
 	}
 
-enumValue : name '=' intLit ';' {
-        $$ = ast.NewEnumValueNode($1, $2, $3, nil, $4)
+enumValue : enumElementName '=' intLit ';' {
+		$$ = ast.NewEnumValueNode($1, $2, $3, nil, $4)
 	}
-	|  name '=' intLit compactOptions ';' {
-        $$ = ast.NewEnumValueNode($1, $2, $3, $4, $5)
+	|  enumElementName '=' intLit compactOptions ';' {
+		$$ = ast.NewEnumValueNode($1, $2, $3, $4, $5)
 	}
 
 message : _MESSAGE name '{' messageDecls '}' {
-        $$ = ast.NewMessageNode($1.ToKeyword(), $2, $3, $4, $5)
+		$$ = ast.NewMessageNode($1.ToKeyword(), $2, $3, $4, $5)
 	}
 
 messageDecls : messageDecls messageDecl {
-        if $2 != nil {
-    		$$ = append($1, $2)
-        } else {
-            $$ = $1
-        }
+		if $2 != nil {
+			$$ = append($1, $2)
+		} else {
+			$$ = $1
+		}
 	}
 	| messageDecl {
-	    if $1 != nil {
-	        $$ = []ast.MessageElement{$1}
-        } else {
-            $$ = nil
-        }
+		if $1 != nil {
+			$$ = []ast.MessageElement{$1}
+		} else {
+			$$ = nil
+		}
 	}
 	| {
 		$$ = nil
 	}
 
-messageDecl : field {
+messageDecl : msgField {
 		$$ = $1
 	}
 	| enum {
@@ -781,35 +852,35 @@ messageDecl : field {
 		$$ = ast.NewEmptyDeclNode($1)
 	}
 	| error ';' {
-	    $$ = nil
+		$$ = nil
 	}
 	| error {
-	    $$ = nil
+		$$ = nil
 	}
 
 extend : _EXTEND typeIdent '{' extendDecls '}' {
-        $$ = ast.NewExtendNode($1.ToKeyword(), $2, $3, $4, $5)
+		$$ = ast.NewExtendNode($1.ToKeyword(), $2, $3, $4, $5)
 	}
 
 extendDecls : extendDecls extendDecl {
-        if $2 != nil {
-    		$$ = append($1, $2)
-        } else {
-            $$ = $1
-        }
+		if $2 != nil {
+			$$ = append($1, $2)
+		} else {
+			$$ = $1
+		}
 	}
 	| extendDecl {
-	    if $1 != nil {
-	        $$ = []ast.ExtendElement{$1}
-        } else {
-            $$ = nil
-        }
+		if $1 != nil {
+			$$ = []ast.ExtendElement{$1}
+		} else {
+			$$ = nil
+		}
 	}
 	| {
 		$$ = nil
 	}
 
-extendDecl : field {
+extendDecl : extField {
 		$$ = $1
 	}
 	| group {
@@ -819,29 +890,29 @@ extendDecl : field {
 		$$ = ast.NewEmptyDeclNode($1)
 	}
 	| error ';' {
-	    $$ = nil
+		$$ = nil
 	}
 	| error {
-	    $$ = nil
+		$$ = nil
 	}
 
 service : _SERVICE name '{' serviceDecls '}' {
-        $$ = ast.NewServiceNode($1.ToKeyword(), $2, $3, $4, $5)
+		$$ = ast.NewServiceNode($1.ToKeyword(), $2, $3, $4, $5)
 	}
 
 serviceDecls : serviceDecls serviceDecl {
-        if $2 != nil {
-    		$$ = append($1, $2)
-        } else {
-            $$ = $1
-        }
+		if $2 != nil {
+			$$ = append($1, $2)
+		} else {
+			$$ = $1
+		}
 	}
 	| serviceDecl {
-	    if $1 != nil {
-	        $$ = []ast.ServiceElement{$1}
-        } else {
-            $$ = nil
-        }
+		if $1 != nil {
+			$$ = []ast.ServiceElement{$1}
+		} else {
+			$$ = nil
+		}
 	}
 	| {
 		$$ = nil
@@ -860,17 +931,17 @@ serviceDecl : option {
 		$$ = ast.NewEmptyDeclNode($1)
 	}
 	| error ';' {
-	    $$ = nil
+		$$ = nil
 	}
 	| error {
-	    $$ = nil
+		$$ = nil
 	}
 
 rpc : _RPC name rpcType _RETURNS rpcType ';' {
-        $$ = ast.NewRPCNode($1.ToKeyword(), $2, $3, $4.ToKeyword(), $5, $6)
+		$$ = ast.NewRPCNode($1.ToKeyword(), $2, $3, $4.ToKeyword(), $5, $6)
 	}
 	| _RPC name rpcType _RETURNS rpcType '{' rpcDecls '}' {
-        $$ = ast.NewRPCNodeWithBody($1.ToKeyword(), $2, $3, $4.ToKeyword(), $5, $6, $7, $8)
+		$$ = ast.NewRPCNodeWithBody($1.ToKeyword(), $2, $3, $4.ToKeyword(), $5, $6, $7, $8)
 	}
 
 rpcType : '(' _STREAM typeIdent ')' {
@@ -881,18 +952,18 @@ rpcType : '(' _STREAM typeIdent ')' {
 	}
 
 rpcDecls : rpcDecls rpcDecl {
-        if $2 != nil {
-    		$$ = append($1, $2)
-        } else {
-            $$ = $1
-        }
+		if $2 != nil {
+			$$ = append($1, $2)
+		} else {
+			$$ = $1
+		}
 	}
 	| rpcDecl {
-	    if $1 != nil {
-	        $$ = []ast.RPCElement{$1}
-        } else {
-            $$ = nil
-        }
+		if $1 != nil {
+			$$ = []ast.RPCElement{$1}
+		} else {
+			$$ = nil
+		}
 	}
 	| {
 		$$ = nil
@@ -905,12 +976,174 @@ rpcDecl : option {
 		$$ = ast.NewEmptyDeclNode($1)
 	}
 	| error ';' {
-	    $$ = nil
+		$$ = nil
 	}
 	| error {
-	    $$ = nil
+		$$ = nil
 	}
 
+// excludes message, enum, oneof, extensions, reserved, extend,
+//   option, optional, required, and repeated
+msgElementName : _NAME
+	| _SYNTAX
+	| _IMPORT
+	| _WEAK
+	| _PUBLIC
+	| _PACKAGE
+	| _TRUE
+	| _FALSE
+	| _INF
+	| _NAN
+	| _DOUBLE
+	| _FLOAT
+	| _INT32
+	| _INT64
+	| _UINT32
+	| _UINT64
+	| _SINT32
+	| _SINT64
+	| _FIXED32
+	| _FIXED64
+	| _SFIXED32
+	| _SFIXED64
+	| _BOOL
+	| _STRING
+	| _BYTES
+	| _GROUP
+	| _MAP
+	| _TO
+	| _MAX
+	| _SERVICE
+	| _RPC
+	| _STREAM
+	| _RETURNS
+
+// excludes optional, required, and repeated
+extElementName : _NAME
+	| _SYNTAX
+	| _IMPORT
+	| _WEAK
+	| _PUBLIC
+	| _PACKAGE
+	| _OPTION
+	| _TRUE
+	| _FALSE
+	| _INF
+	| _NAN
+	| _DOUBLE
+	| _FLOAT
+	| _INT32
+	| _INT64
+	| _UINT32
+	| _UINT64
+	| _SINT32
+	| _SINT64
+	| _FIXED32
+	| _FIXED64
+	| _SFIXED32
+	| _SFIXED64
+	| _BOOL
+	| _STRING
+	| _BYTES
+	| _GROUP
+	| _ONEOF
+	| _MAP
+	| _EXTENSIONS
+	| _TO
+	| _MAX
+	| _RESERVED
+	| _ENUM
+	| _MESSAGE
+	| _EXTEND
+	| _SERVICE
+	| _RPC
+	| _STREAM
+	| _RETURNS
+
+// excludes reserved, option
+enumElementName : _NAME
+	| _SYNTAX
+	| _IMPORT
+	| _WEAK
+	| _PUBLIC
+	| _PACKAGE
+	| _TRUE
+	| _FALSE
+	| _INF
+	| _NAN
+	| _REPEATED
+	| _OPTIONAL
+	| _REQUIRED
+	| _DOUBLE
+	| _FLOAT
+	| _INT32
+	| _INT64
+	| _UINT32
+	| _UINT64
+	| _SINT32
+	| _SINT64
+	| _FIXED32
+	| _FIXED64
+	| _SFIXED32
+	| _SFIXED64
+	| _BOOL
+	| _STRING
+	| _BYTES
+	| _GROUP
+	| _ONEOF
+	| _MAP
+	| _EXTENSIONS
+	| _TO
+	| _MAX
+	| _ENUM
+	| _MESSAGE
+	| _EXTEND
+	| _SERVICE
+	| _RPC
+	| _STREAM
+	| _RETURNS
+
+// excludes option, optional, required, and repeated
+oneofElementName : _NAME
+	| _SYNTAX
+	| _IMPORT
+	| _WEAK
+	| _PUBLIC
+	| _PACKAGE
+	| _TRUE
+	| _FALSE
+	| _INF
+	| _NAN
+	| _DOUBLE
+	| _FLOAT
+	| _INT32
+	| _INT64
+	| _UINT32
+	| _UINT64
+	| _SINT32
+	| _SINT64
+	| _FIXED32
+	| _FIXED64
+	| _SFIXED32
+	| _SFIXED64
+	| _BOOL
+	| _STRING
+	| _BYTES
+	| _GROUP
+	| _ONEOF
+	| _MAP
+	| _EXTENSIONS
+	| _TO
+	| _MAX
+	| _RESERVED
+	| _ENUM
+	| _MESSAGE
+	| _EXTEND
+	| _SERVICE
+	| _RPC
+	| _STREAM
+	| _RETURNS
+
 name : _NAME
 	| _SYNTAX
 	| _IMPORT
diff --git a/desc/protoparse/proto.y.go b/desc/protoparse/proto.y.go
index 1b7c6e8..61d9038 100644
--- a/desc/protoparse/proto.y.go
+++ b/desc/protoparse/proto.y.go
@@ -210,7 +210,7 @@ const protoEofCode = 1
 const protoErrCode = 2
 const protoInitialStackSize = 16
 
-//line proto.y:958
+//line proto.y:1191
 
 //line yacctab:1
 var protoExca = [...]int{
@@ -230,383 +230,437 @@ var protoExca = [...]int{
 	1, 3,
 	-2, 0,
 	-1, 95,
-	55, 158,
+	55, 178,
 	-2, 0,
 	-1, 96,
-	55, 146,
+	55, 166,
 	-2, 0,
 	-1, 97,
-	55, 175,
+	55, 195,
 	-2, 0,
 	-1, 99,
-	55, 184,
+	55, 204,
 	-2, 0,
 	-1, 110,
-	55, 47,
+	55, 53,
 	-2, 0,
-	-1, 170,
-	55, 45,
-	61, 45,
+	-1, 289,
+	55, 51,
+	61, 51,
 	-2, 0,
-	-1, 225,
-	61, 47,
+	-1, 352,
+	61, 53,
 	-2, 0,
-	-1, 240,
-	55, 96,
+	-1, 367,
+	55, 116,
 	-2, 0,
-	-1, 268,
-	61, 47,
+	-1, 401,
+	61, 53,
 	-2, 0,
-	-1, 311,
-	61, 47,
+	-1, 489,
+	61, 53,
 	-2, 0,
-	-1, 348,
-	55, 158,
+	-1, 533,
+	55, 178,
 	-2, 0,
-	-1, 352,
-	55, 158,
+	-1, 537,
+	55, 178,
 	-2, 0,
-	-1, 356,
-	55, 158,
+	-1, 541,
+	55, 178,
 	-2, 0,
-	-1, 366,
-	55, 196,
+	-1, 559,
+	55, 216,
 	-2, 0,
-	-1, 373,
-	55, 158,
+	-1, 566,
+	55, 178,
 	-2, 0,
-	-1, 376,
-	55, 158,
+	-1, 569,
+	55, 178,
 	-2, 0,
-	-1, 379,
-	55, 158,
+	-1, 572,
+	55, 178,
 	-2, 0,
-	-1, 397,
-	55, 158,
+	-1, 593,
+	55, 178,
 	-2, 0,
-	-1, 409,
-	55, 158,
+	-1, 605,
+	55, 178,
 	-2, 0,
 }
 
 const protoPrivate = 57344
 
-const protoLast = 2179
+const protoLast = 2321
 
 var protoAct = [...]int{
-	31, 118, 117, 125, 8, 310, 8, 8, 383, 169,
-	263, 288, 207, 198, 308, 75, 205, 236, 77, 79,
-	80, 281, 84, 134, 192, 105, 8, 107, 106, 124,
-	162, 143, 146, 82, 397, 356, 395, 156, 354, 340,
-	119, 352, 339, 26, 81, 350, 348, 237, 237, 346,
-	30, 237, 85, 237, 237, 87, 88, 89, 332, 237,
-	237, 322, 324, 299, 237, 235, 272, 271, 367, 338,
-	208, 29, 208, 237, 116, 264, 237, 222, 237, 222,
-	237, 223, 110, 222, 208, 221, 370, 221, 345, 388,
-	225, 221, 315, 109, 77, 200, 369, 152, 104, 364,
-	147, 344, 94, 163, 314, 222, 303, 220, 387, 115,
-	341, 174, 325, 221, 298, 219, 260, 98, 244, 183,
-	238, 93, 91, 386, 365, 103, 366, 158, 154, 209,
-	217, 209, 409, 407, 17, 191, 80, 79, 157, 379,
-	77, 195, 196, 209, 376, 373, 152, 386, 240, 147,
-	99, 97, 96, 95, 401, 185, 187, 189, 17, 377,
-	374, 81, 371, 363, 358, 163, 335, 197, 216, 329,
-	199, 174, 14, 385, 280, 259, 399, 154, 202, 15,
-	218, 199, 16, 17, 166, 158, 228, 229, 230, 231,
-	232, 233, 214, 211, 243, 17, 157, 385, 14, 226,
-	166, 242, 224, 215, 4, 15, 212, 203, 16, 17,
-	184, 17, 168, 19, 18, 20, 21, 258, 102, 101,
-	100, 90, 13, 86, 109, 25, 174, 362, 361, 167,
-	326, 278, 277, 304, 165, 269, 276, 213, 77, 19,
-	18, 20, 21, 275, 289, 167, 274, 285, 13, 265,
-	165, 273, 267, 283, 241, 234, 204, 92, 297, 24,
-	261, 239, 381, 284, 294, 29, 194, 109, 380, 174,
-	321, 5, 199, 29, 302, 23, 300, 301, 312, 27,
-	28, 122, 11, 286, 11, 11, 120, 10, 306, 10,
-	10, 289, 320, 319, 23, 330, 331, 323, 318, 328,
-	317, 316, 121, 9, 11, 9, 9, 181, 179, 10,
-	296, 294, 174, 194, 333, 336, 279, 262, 180, 178,
-	176, 342, 334, 29, 164, 9, 77, 109, 3, 337,
-	177, 22, 360, 161, 347, 349, 351, 353, 355, 357,
-	12, 283, 109, 155, 148, 145, 123, 359, 206, 193,
-	149, 372, 128, 287, 141, 375, 368, 127, 291, 378,
-	126, 290, 170, 171, 245, 108, 173, 76, 382, 282,
-	384, 7, 6, 2, 183, 1, 390, 183, 0, 392,
-	183, 0, 394, 0, 0, 0, 384, 0, 109, 109,
-	0, 400, 183, 0, 183, 0, 183, 0, 396, 398,
-	408, 0, 402, 403, 0, 0, 0, 0, 0, 0,
-	183, 0, 411, 183, 309, 0, 29, 114, 111, 32,
-	33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
-	43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
-	53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
-	63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
-	73, 74, 0, 0, 0, 0, 110, 0, 0, 0,
-	0, 0, 0, 0, 311, 113, 112, 0, 0, 0,
-	307, 29, 114, 111, 32, 33, 34, 35, 36, 37,
-	38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
-	48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
-	58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
-	68, 69, 70, 71, 72, 73, 74, 0, 0, 0,
-	0, 110, 0, 0, 0, 0, 0, 0, 0, 268,
-	113, 112, 0, 0, 266, 29, 114, 111, 32, 33,
-	34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
-	44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
-	54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-	64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
-	74, 0, 0, 0, 0, 110, 0, 0, 0, 0,
-	0, 0, 0, 311, 113, 112, 29, 114, 111, 32,
-	33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
-	43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
-	53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
-	63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
-	73, 74, 0, 0, 0, 0, 110, 0, 0, 0,
-	0, 0, 343, 0, 0, 113, 112, 32, 33, 34,
-	35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
-	45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
-	55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
-	65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
-	246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
-	256, 257, 0, 313, 0, 0, 0, 175, 32, 33,
-	34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
-	44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
-	54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-	64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
-	74, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 270, 0, 0, 0, 175, 32,
-	33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
-	43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
-	53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
-	63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
-	73, 74, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 172, 0, 0, 0, 175,
+	31, 118, 117, 125, 8, 396, 8, 8, 488, 81,
+	486, 414, 363, 288, 579, 421, 328, 107, 77, 79,
+	80, 82, 84, 326, 317, 311, 8, 106, 105, 124,
+	281, 228, 139, 26, 177, 593, 416, 591, 30, 525,
+	555, 553, 85, 551, 541, 87, 88, 89, 364, 539,
+	537, 535, 364, 531, 75, 364, 364, 364, 364, 533,
+	524, 519, 512, 364, 364, 500, 364, 473, 364, 362,
+	502, 405, 364, 560, 404, 329, 364, 364, 523, 397,
+	364, 329, 364, 349, 364, 29, 329, 116, 94, 350,
+	110, 348, 563, 109, 77, 320, 562, 584, 352, 349,
+	178, 104, 550, 282, 529, 98, 349, 348, 530, 492,
+	349, 293, 347, 103, 348, 493, 583, 477, 348, 302,
+	346, 526, 503, 472, 388, 371, 365, 230, 511, 185,
+	115, 339, 321, 93, 330, 310, 91, 314, 315, 344,
+	330, 304, 306, 308, 14, 330, 285, 582, 605, 572,
+	4, 15, 569, 566, 16, 17, 318, 17, 17, 558,
+	367, 559, 14, 319, 316, 285, 582, 99, 97, 15,
+	96, 95, 16, 17, 603, 597, 17, 17, 577, 576,
+	178, 575, 570, 567, 564, 19, 18, 20, 21, 557,
+	549, 286, 543, 515, 13, 507, 284, 581, 413, 340,
+	595, 387, 318, 19, 18, 20, 21, 370, 369, 185,
+	286, 323, 13, 342, 333, 284, 581, 324, 303, 287,
+	102, 101, 100, 90, 86, 25, 547, 546, 504, 480,
+	479, 478, 411, 410, 409, 408, 407, 337, 406, 394,
+	368, 361, 325, 334, 335, 336, 92, 24, 482, 418,
+	389, 366, 122, 11, 574, 11, 11, 230, 573, 332,
+	338, 373, 374, 375, 376, 377, 378, 379, 380, 381,
+	382, 383, 384, 120, 10, 11, 10, 10, 121, 9,
+	518, 9, 9, 517, 282, 419, 516, 343, 29, 5,
+	293, 300, 298, 23, 27, 28, 10, 29, 313, 499,
+	498, 9, 299, 345, 353, 355, 356, 357, 358, 359,
+	360, 341, 23, 297, 295, 497, 496, 495, 494, 481,
+	351, 470, 313, 412, 296, 390, 29, 3, 283, 280,
+	22, 12, 227, 179, 176, 391, 392, 393, 123, 327,
+	312, 180, 386, 385, 128, 420, 137, 127, 424, 126,
+	229, 109, 119, 293, 423, 289, 290, 427, 236, 134,
+	429, 395, 237, 140, 183, 77, 402, 431, 239, 143,
+	372, 422, 108, 292, 76, 578, 415, 7, 400, 398,
+	6, 2, 1, 0, 0, 0, 0, 0, 0, 318,
+	0, 417, 0, 0, 0, 0, 471, 0, 0, 474,
+	109, 0, 293, 0, 0, 0, 476, 484, 0, 0,
+	0, 0, 475, 0, 0, 490, 0, 0, 0, 0,
+	0, 0, 0, 0, 422, 501, 0, 0, 508, 509,
+	0, 0, 0, 0, 426, 0, 506, 0, 0, 432,
+	433, 434, 435, 436, 437, 17, 438, 439, 440, 441,
+	0, 0, 510, 442, 443, 444, 445, 446, 447, 448,
+	449, 450, 451, 452, 453, 454, 455, 456, 428, 457,
+	458, 459, 460, 461, 462, 463, 464, 465, 466, 467,
+	468, 469, 514, 513, 425, 0, 0, 505, 521, 0,
+	293, 430, 0, 522, 520, 0, 0, 0, 0, 0,
+	0, 0, 0, 527, 77, 109, 0, 532, 534, 536,
+	538, 540, 542, 545, 0, 544, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 109, 0, 552,
+	554, 556, 0, 548, 0, 0, 565, 561, 0, 0,
+	568, 0, 0, 0, 571, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 580, 0, 0, 0, 302, 0, 586,
+	302, 0, 588, 302, 0, 590, 0, 0, 0, 0,
+	0, 0, 580, 0, 109, 109, 592, 594, 302, 0,
+	302, 0, 302, 596, 598, 599, 604, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 302, 0, 607, 302,
+	487, 0, 29, 114, 111, 32, 33, 34, 35, 36,
+	37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+	47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+	57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+	67, 68, 69, 70, 71, 72, 73, 74, 0, 0,
+	0, 0, 110, 0, 0, 0, 0, 0, 0, 0,
+	489, 113, 112, 0, 0, 0, 485, 29, 114, 111,
 	32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
 	42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
 	52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
 	62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
-	72, 73, 74, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	175, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-	41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
-	51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
-	61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
-	71, 72, 73, 74, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 130, 0, 0, 0, 78,
-	32, 33, 34, 35, 36, 37, 139, 39, 40, 41,
-	42, 133, 132, 131, 46, 47, 48, 49, 50, 51,
-	52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
-	140, 144, 138, 65, 66, 142, 135, 136, 137, 71,
-	72, 73, 74, 0, 0, 129, 0, 0, 412, 130,
-	0, 0, 83, 0, 32, 33, 34, 35, 36, 37,
-	139, 39, 40, 41, 42, 133, 132, 131, 46, 47,
-	48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
-	58, 59, 60, 61, 140, 144, 138, 65, 66, 142,
-	135, 136, 137, 71, 72, 73, 74, 0, 0, 129,
-	0, 0, 410, 130, 0, 0, 83, 0, 32, 33,
-	34, 35, 36, 37, 139, 39, 40, 41, 42, 133,
-	132, 131, 46, 47, 48, 49, 50, 51, 52, 53,
-	54, 55, 56, 57, 58, 59, 60, 61, 140, 144,
-	138, 65, 66, 142, 135, 136, 137, 71, 72, 73,
-	74, 0, 0, 129, 0, 0, 406, 130, 0, 0,
-	83, 0, 32, 33, 34, 35, 36, 37, 139, 39,
-	40, 41, 42, 133, 132, 131, 46, 47, 48, 49,
-	50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
-	60, 61, 140, 144, 138, 65, 66, 142, 135, 136,
-	137, 71, 72, 73, 74, 0, 0, 129, 0, 0,
-	405, 130, 0, 0, 83, 0, 32, 33, 34, 35,
-	36, 37, 139, 39, 40, 41, 42, 133, 132, 131,
-	46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
-	56, 57, 58, 59, 60, 61, 140, 144, 138, 65,
-	66, 142, 135, 136, 137, 71, 72, 73, 74, 0,
-	0, 129, 0, 0, 404, 130, 0, 0, 83, 0,
-	32, 33, 34, 35, 36, 37, 139, 39, 40, 41,
-	42, 133, 132, 131, 46, 47, 48, 49, 50, 51,
-	52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
-	140, 144, 138, 65, 66, 142, 135, 136, 137, 71,
-	72, 73, 74, 0, 0, 129, 0, 0, 393, 130,
-	0, 0, 83, 0, 32, 33, 34, 35, 36, 37,
-	139, 39, 40, 41, 42, 133, 132, 131, 46, 47,
-	48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
-	58, 59, 60, 61, 140, 144, 138, 65, 66, 142,
-	135, 136, 137, 71, 72, 73, 74, 0, 0, 129,
-	0, 0, 391, 130, 0, 0, 83, 0, 32, 33,
-	34, 35, 36, 37, 139, 39, 40, 41, 42, 133,
-	132, 131, 46, 47, 48, 49, 50, 51, 52, 53,
-	54, 55, 56, 57, 58, 59, 60, 61, 140, 144,
-	138, 65, 66, 142, 135, 136, 137, 71, 72, 73,
-	74, 0, 0, 129, 0, 0, 389, 293, 0, 0,
-	83, 0, 32, 33, 34, 35, 36, 37, 139, 39,
-	40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
-	50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
-	60, 295, 62, 63, 64, 65, 66, 67, 68, 69,
-	70, 71, 72, 73, 74, 0, 0, 292, 0, 0,
-	327, 160, 0, 0, 83, 0, 32, 33, 34, 35,
-	36, 37, 38, 39, 40, 41, 42, 133, 132, 131,
-	46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
-	56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
-	66, 67, 68, 69, 70, 71, 72, 73, 74, 0,
-	0, 159, 0, 0, 210, 130, 0, 0, 83, 0,
-	32, 33, 34, 35, 36, 37, 139, 39, 40, 41,
-	42, 133, 132, 131, 46, 47, 48, 49, 50, 51,
-	52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
-	140, 144, 138, 65, 66, 142, 135, 136, 137, 71,
-	72, 73, 74, 0, 0, 129, 0, 0, 182, 130,
-	0, 0, 83, 0, 32, 33, 34, 35, 36, 37,
-	139, 39, 40, 41, 42, 133, 132, 131, 46, 47,
+	72, 73, 74, 0, 0, 0, 0, 110, 0, 0,
+	0, 0, 0, 0, 0, 401, 113, 112, 0, 0,
+	399, 29, 114, 111, 32, 33, 34, 35, 36, 37,
+	38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
 	48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
-	58, 59, 60, 61, 140, 144, 138, 65, 66, 142,
-	135, 136, 137, 71, 72, 73, 74, 0, 0, 129,
-	0, 0, 293, 0, 0, 0, 83, 32, 33, 34,
-	35, 36, 37, 139, 39, 40, 41, 42, 43, 44,
-	45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
-	55, 56, 57, 58, 59, 60, 295, 62, 63, 64,
-	65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
-	0, 0, 292, 0, 0, 160, 0, 0, 0, 83,
-	32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
-	42, 133, 132, 131, 46, 47, 48, 49, 50, 51,
-	52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
-	62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
-	72, 73, 74, 0, 0, 159, 0, 0, 227, 0,
-	0, 0, 83, 32, 33, 34, 35, 36, 37, 38,
+	58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+	68, 69, 70, 71, 72, 73, 74, 0, 0, 0,
+	0, 110, 0, 0, 0, 0, 0, 0, 0, 489,
+	113, 112, 29, 114, 111, 32, 33, 34, 35, 36,
+	37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+	47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+	57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+	67, 68, 69, 70, 71, 72, 73, 74, 0, 0,
+	0, 0, 110, 0, 0, 0, 0, 0, 528, 0,
+	0, 113, 112, 32, 33, 34, 35, 36, 37, 38,
 	39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
 	49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
 	59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
 	69, 70, 71, 72, 73, 74, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 83, 32, 33, 34, 35,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 491,
+	0, 0, 0, 294, 32, 33, 34, 35, 36, 37,
+	38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+	48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+	58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+	68, 69, 70, 71, 72, 73, 74, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	403, 0, 0, 0, 294, 32, 33, 34, 35, 36,
+	37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+	47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+	57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+	67, 68, 69, 70, 71, 72, 73, 74, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 291, 0, 0, 0, 294, 32, 33, 34, 35,
 	36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
 	46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
 	56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
 	66, 67, 68, 69, 70, 71, 72, 73, 74, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 83, 32,
-	33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
-	43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
-	53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
-	63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
-	305, 74, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 83, 32, 33, 34, 35, 36, 37, 38, 39,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 294, 32, 33, 34,
+	35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+	45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+	55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+	65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 130, 0, 0, 0, 78, 144, 145, 146, 147,
+	148, 149, 17, 150, 151, 152, 153, 133, 132, 131,
+	154, 155, 156, 157, 158, 159, 160, 161, 162, 163,
+	164, 165, 166, 167, 168, 169, 136, 142, 135, 170,
+	171, 138, 19, 18, 20, 172, 173, 174, 175, 0,
+	0, 129, 0, 0, 608, 130, 0, 0, 141, 0,
+	144, 145, 146, 147, 148, 149, 17, 150, 151, 152,
+	153, 133, 132, 131, 154, 155, 156, 157, 158, 159,
+	160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
+	136, 142, 135, 170, 171, 138, 19, 18, 20, 172,
+	173, 174, 175, 0, 0, 129, 0, 0, 606, 130,
+	0, 0, 141, 0, 144, 145, 146, 147, 148, 149,
+	17, 150, 151, 152, 153, 133, 132, 131, 154, 155,
+	156, 157, 158, 159, 160, 161, 162, 163, 164, 165,
+	166, 167, 168, 169, 136, 142, 135, 170, 171, 138,
+	19, 18, 20, 172, 173, 174, 175, 0, 0, 129,
+	0, 0, 602, 130, 0, 0, 141, 0, 144, 145,
+	146, 147, 148, 149, 17, 150, 151, 152, 153, 133,
+	132, 131, 154, 155, 156, 157, 158, 159, 160, 161,
+	162, 163, 164, 165, 166, 167, 168, 169, 136, 142,
+	135, 170, 171, 138, 19, 18, 20, 172, 173, 174,
+	175, 0, 0, 129, 0, 0, 601, 130, 0, 0,
+	141, 0, 144, 145, 146, 147, 148, 149, 17, 150,
+	151, 152, 153, 133, 132, 131, 154, 155, 156, 157,
+	158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
+	168, 169, 136, 142, 135, 170, 171, 138, 19, 18,
+	20, 172, 173, 174, 175, 0, 0, 129, 0, 0,
+	600, 130, 0, 0, 141, 0, 144, 145, 146, 147,
+	148, 149, 17, 150, 151, 152, 153, 133, 132, 131,
+	154, 155, 156, 157, 158, 159, 160, 161, 162, 163,
+	164, 165, 166, 167, 168, 169, 136, 142, 135, 170,
+	171, 138, 19, 18, 20, 172, 173, 174, 175, 0,
+	0, 129, 0, 0, 589, 130, 0, 0, 141, 0,
+	144, 145, 146, 147, 148, 149, 17, 150, 151, 152,
+	153, 133, 132, 131, 154, 155, 156, 157, 158, 159,
+	160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
+	136, 142, 135, 170, 171, 138, 19, 18, 20, 172,
+	173, 174, 175, 0, 0, 129, 0, 0, 587, 130,
+	0, 0, 141, 0, 144, 145, 146, 147, 148, 149,
+	17, 150, 151, 152, 153, 133, 132, 131, 154, 155,
+	156, 157, 158, 159, 160, 161, 162, 163, 164, 165,
+	166, 167, 168, 169, 136, 142, 135, 170, 171, 138,
+	19, 18, 20, 172, 173, 174, 175, 0, 0, 129,
+	0, 0, 585, 232, 0, 0, 141, 0, 240, 241,
+	242, 243, 244, 245, 246, 247, 248, 249, 250, 235,
+	234, 233, 251, 252, 253, 254, 255, 256, 257, 258,
+	259, 260, 261, 262, 263, 264, 265, 266, 267, 268,
+	269, 270, 271, 272, 273, 274, 275, 276, 277, 278,
+	279, 0, 0, 231, 0, 0, 331, 130, 0, 0,
+	238, 0, 144, 145, 146, 147, 148, 149, 17, 150,
+	151, 152, 153, 133, 132, 131, 154, 155, 156, 157,
+	158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
+	168, 169, 136, 142, 135, 170, 171, 138, 19, 18,
+	20, 172, 173, 174, 175, 0, 0, 129, 0, 0,
+	301, 130, 0, 0, 141, 0, 144, 145, 146, 147,
+	148, 149, 17, 150, 151, 152, 153, 133, 132, 131,
+	154, 155, 156, 157, 158, 159, 160, 161, 162, 163,
+	164, 165, 166, 167, 168, 169, 136, 142, 135, 170,
+	171, 138, 19, 18, 20, 172, 173, 174, 175, 0,
+	0, 129, 0, 0, 232, 0, 0, 0, 141, 240,
+	241, 242, 243, 244, 245, 246, 247, 248, 249, 250,
+	235, 234, 233, 251, 252, 253, 254, 255, 256, 257,
+	258, 259, 260, 261, 262, 263, 264, 265, 266, 267,
+	268, 269, 270, 271, 272, 273, 274, 275, 276, 277,
+	278, 279, 0, 0, 231, 0, 0, 354, 0, 0,
+	0, 238, 32, 33, 34, 35, 36, 37, 38, 39,
 	40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
 	50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
-	60, 190, 62, 63, 64, 65, 66, 67, 68, 69,
+	60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
 	70, 71, 72, 73, 74, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 83, 32, 33, 34, 35, 36,
 	37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
 	47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
-	57, 58, 59, 60, 188, 62, 63, 64, 65, 66,
+	57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
 	67, 68, 69, 70, 71, 72, 73, 74, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 83, 32, 33,
 	34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
 	44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
-	54, 55, 56, 57, 58, 59, 60, 186, 62, 63,
-	64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
-	74, 0, 0, 0, 0, 0, 151, 0, 0, 0,
-	83, 32, 33, 34, 35, 36, 37, 139, 39, 40,
+	54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+	64, 65, 66, 67, 68, 69, 70, 71, 72, 483,
+	74, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	83, 32, 33, 34, 35, 36, 37, 38, 39, 40,
 	41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
 	51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
-	61, 62, 63, 64, 65, 66, 153, 68, 69, 70,
-	71, 72, 73, 74, 0, 151, 150, 0, 0, 201,
-	32, 33, 34, 35, 36, 37, 139, 39, 40, 41,
-	42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
-	52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
-	62, 63, 64, 65, 66, 153, 68, 69, 70, 71,
-	72, 73, 74, 0, 0, 150, 32, 33, 34, 35,
-	36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
-	46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
-	56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
-	66, 67, 68, 69, 70, 71, 72, 73, 74,
+	309, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+	71, 72, 73, 74, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 83, 32, 33, 34, 35, 36, 37,
+	38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+	48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+	58, 59, 60, 307, 62, 63, 64, 65, 66, 67,
+	68, 69, 70, 71, 72, 73, 74, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 83, 32, 33, 34,
+	35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+	45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+	55, 56, 57, 58, 59, 60, 305, 62, 63, 64,
+	65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+	0, 0, 0, 0, 0, 426, 0, 0, 0, 83,
+	432, 433, 434, 435, 436, 437, 17, 438, 439, 440,
+	441, 0, 0, 0, 442, 443, 444, 445, 446, 447,
+	448, 449, 450, 451, 452, 453, 454, 455, 456, 428,
+	457, 458, 459, 460, 461, 462, 463, 464, 465, 466,
+	467, 468, 469, 0, 0, 425, 0, 0, 182, 0,
+	0, 0, 430, 186, 187, 188, 189, 190, 191, 17,
+	192, 193, 194, 195, 196, 197, 198, 199, 200, 201,
+	202, 203, 204, 205, 206, 207, 208, 209, 210, 211,
+	212, 213, 214, 215, 216, 217, 218, 219, 184, 220,
+	221, 222, 223, 224, 225, 226, 0, 182, 181, 0,
+	0, 322, 186, 187, 188, 189, 190, 191, 17, 192,
+	193, 194, 195, 196, 197, 198, 199, 200, 201, 202,
+	203, 204, 205, 206, 207, 208, 209, 210, 211, 212,
+	213, 214, 215, 216, 217, 218, 219, 184, 220, 221,
+	222, 223, 224, 225, 226, 0, 0, 181, 32, 33,
+	34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+	44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+	54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+	64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+	74,
 }
 
 var protoPact = [...]int{
-	196, -1000, 170, 170, 208, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, -1000, -1000, 173, 269, 2129, 904, 2129, 2129,
-	1769, 2129, 170, -1000, 319, -1000, 171, 319, 319, 319,
-	169, 63, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	142, -1000, 160, 160, 196, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, 173, 284, 2271, 1100, 2271, 2271,
+	1858, 2271, 160, -1000, 322, -1000, 172, 322, 322, 322,
+	171, 77, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, 195, 74, -1000, 1858, 117,
+	116, 114, -1000, 2271, 113, 170, -1000, 169, 168, -1000,
+	-1000, 2271, 798, 1100, 21, 1699, 2225, 1752, -1000, 163,
+	-1000, -1000, -1000, -1000, 167, -1000, -1000, -1000, -1000, -1000,
+	1039, -1000, 308, 286, -1000, -1000, -1000, 1645, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	166, 2070, 2017, 1964, 2271, 317, 2271, 2271, 293, -1000,
+	-1000, 2271, 33, 73, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, 2176, -1000, -1000, -1000,
+	-1000, -1000, 165, 191, 81, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, 1591, -1000, -1000,
+	-1000, -1000, 162, 2070, 2017, 1964, 2271, -1000, 2271, 72,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	-1000, -1000, -1000, -1000, -1000, 206, 62, -1000, 1769, 99,
-	98, 97, -1000, 2129, 96, 168, -1000, 167, 166, -1000,
-	-1000, 2129, 602, 904, 8, 1557, 2083, 1663, -1000, 198,
-	-1000, -1000, -1000, -1000, 160, -1000, -1000, -1000, -1000, -1000,
-	843, -1000, 314, 302, -1000, -1000, -1000, 1503, -1000, -1000,
+	144, -1000, -1000, -1000, -1000, 161, 2271, -1000, 84, 1039,
+	60, 58, 36, -1000, 1805, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, 2271, 2271, 2271, 2271, 2271, 2271,
+	190, 17, 66, 211, 106, 189, 156, 155, 65, -1000,
+	238, 2271, -1000, -1000, -1000, 70, 149, 64, 210, -1000,
+	320, -1000, -1000, -1000, 2271, 2271, 2271, 188, -1000, 2271,
+	-1000, -1000, -1000, 14, -1000, -1000, -1000, -1000, -1000, -1000,
+	673, -1000, 978, 6, 3, 187, 185, 184, 183, 182,
+	181, 318, -1000, 146, 1100, 317, 244, 2123, 316, -1000,
+	-1000, 322, 63, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, 15, -1000, 70, 76,
+	-1000, 180, 179, 178, 314, -1000, 199, 1911, -1000, 608,
+	-1000, 917, 48, 54, -1000, -1000, 313, 312, 311, 310,
+	295, 294, 13, -1000, 2, 62, 177, -1000, -1000, -1000,
+	432, -1000, -1000, -1000, -1000, -1000, 143, 2271, 2271, -1000,
+	2271, 69, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
-	158, 1981, 1928, 1875, 2129, 2129, 2129, 1769, 308, 904,
-	2129, 2129, 261, -1000, 33, 2034, -1000, -1000, -1000, -1000,
-	-1000, 155, 205, 67, -1000, 1449, -1000, -1000, -1000, -1000,
-	154, 182, -1000, -1000, -1000, -1000, 151, 2129, -1000, 75,
-	843, 55, 53, 28, -1000, 1716, -1000, -1000, -1000, -1000,
-	-1000, -1000, -1000, -1000, -1000, 2129, 2129, 2129, 2129, 2129,
-	2129, 204, 13, 60, 221, 94, 203, 149, 142, 58,
-	687, -1000, -1000, -1000, 79, 123, 56, 220, -1000, 312,
-	-1000, -1000, -1000, -1000, -1000, -1000, 10, -1000, -1000, -1000,
-	-1000, -1000, -1000, 477, -1000, 782, -1, -2, 200, 195,
-	192, 185, 181, 180, 311, -1000, 122, 904, 308, 242,
-	1610, 305, -1000, -1000, 319, 54, -1000, -1000, -1000, -1000,
-	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 11, -1000,
-	79, 65, -1000, 184, 1822, -1000, 412, -1000, 721, 43,
-	31, -1000, -1000, 296, 295, 293, 288, 287, 265, 9,
-	-1000, -6, 52, 179, -1000, -1000, -1000, 1395, -1000, -1000,
-	-1000, -1000, -1000, 117, 2129, 2129, 6, -1000, 1769, -1000,
-	114, -1000, -1000, -1000, 10, 1769, 3, -1000, -26, -29,
-	50, 660, 40, 27, -1000, -1000, -3, -8, -7, -13,
-	-14, -19, -1000, 112, -1000, 904, 602, -1000, -1000, -1000,
-	177, 176, -1000, 111, 38, -1000, 72, 2, -1000, -1000,
-	-1000, 541, 35, 25, -1000, -1000, -1000, 110, 1557, 91,
-	-1000, 108, 1557, 90, -1000, 107, 1557, 85, -1000, -1000,
-	-1000, 263, 257, -1000, -1000, -1000, 145, -1000, -1000, 48,
-	29, -1000, 1341, 1557, -1000, 1287, 1557, -1000, 1233, 1557,
-	-16, -20, 121, -1000, -1000, -1000, 102, 541, 541, -1000,
-	1179, -1000, 1125, -1000, 1071, -1000, 81, 1557, 78, -1000,
-	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1017, 1557,
-	-1000, 963, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+	10, -1000, 1858, -1000, 141, -1000, -1000, -1000, 281, 278,
+	275, 9, 14, 1858, 12, -1000, -8, -29, 61, 856,
+	43, 47, -1000, -1000, 1, 5, -1, -4, -3, -10,
+	-1000, 140, -1000, 1100, 798, -1000, -1000, -1000, 176, 175,
+	-1000, 2271, -1000, 138, 41, -1000, -9, -11, -12, -1000,
+	137, 107, 7, -1000, -1000, -1000, 737, 35, 31, -1000,
+	-1000, -1000, 132, 1699, 99, -1000, 131, 1699, 98, -1000,
+	130, 1699, 95, -1000, -1000, -1000, 253, 249, -1000, -1000,
+	-1000, -1000, 129, -1000, 127, -1000, 126, -1000, -1000, 164,
+	-1000, -1000, 56, 37, -1000, 1537, 1699, -1000, 1483, 1699,
+	-1000, 1429, 1699, -15, -19, -1000, -1000, -1000, 145, -1000,
+	-1000, -1000, 123, 737, 737, -1000, 1375, -1000, 1321, -1000,
+	1267, -1000, 122, 1699, 94, -1000, -1000, -1000, -1000, -1000,
+	-1000, -1000, -1000, -1000, 1213, 1699, -1000, 1159, -1000,
 }
 
 var protoPgo = [...]int{
-	0, 375, 373, 271, 328, 372, 371, 3, 369, 21,
-	8, 368, 367, 366, 15, 17, 5, 25, 28, 365,
-	12, 0, 364, 33, 23, 14, 363, 362, 9, 40,
-	361, 360, 29, 358, 357, 354, 302, 1, 2, 11,
-	353, 13, 352, 350, 31, 349, 348, 24, 16, 346,
-	286, 32, 345, 344, 281, 37, 343, 27, 340, 30,
-	333, 324, 10,
+	0, 382, 381, 289, 327, 380, 377, 3, 376, 11,
+	14, 375, 374, 373, 36, 12, 8, 28, 27, 372,
+	16, 0, 370, 369, 368, 367, 364, 21, 363, 362,
+	360, 9, 359, 358, 357, 10, 356, 355, 13, 354,
+	352, 350, 349, 29, 348, 347, 346, 278, 1, 2,
+	15, 345, 24, 344, 341, 32, 340, 339, 25, 23,
+	338, 273, 34, 334, 333, 252, 31, 332, 17, 331,
+	30, 329, 328, 5,
 }
 
 var protoR1 = [...]int{
 	0, 1, 1, 1, 1, 4, 4, 3, 3, 3,
 	3, 3, 3, 3, 3, 3, 3, 2, 5, 5,
-	5, 6, 23, 23, 7, 14, 14, 12, 12, 16,
-	16, 17, 17, 17, 19, 19, 19, 19, 19, 19,
-	19, 19, 57, 57, 18, 28, 28, 28, 27, 27,
-	27, 27, 27, 27, 26, 26, 26, 26, 26, 26,
-	26, 26, 26, 26, 13, 13, 13, 25, 25, 25,
-	25, 25, 25, 24, 24, 29, 29, 29, 29, 29,
-	29, 29, 29, 15, 9, 9, 8, 32, 32, 32,
-	32, 32, 32, 31, 40, 40, 40, 39, 39, 39,
-	39, 39, 39, 30, 30, 33, 33, 34, 34, 35,
+	5, 6, 27, 27, 28, 28, 29, 29, 30, 30,
+	7, 14, 14, 12, 12, 16, 16, 17, 17, 17,
+	19, 19, 19, 19, 19, 19, 19, 19, 68, 68,
+	18, 38, 38, 38, 37, 37, 37, 37, 37, 37,
+	36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+	13, 13, 13, 35, 35, 35, 35, 35, 35, 31,
+	31, 32, 32, 33, 33, 34, 34, 40, 40, 40,
+	40, 40, 40, 40, 40, 41, 41, 41, 41, 41,
+	41, 41, 41, 15, 9, 9, 8, 43, 43, 43,
+	43, 43, 43, 42, 51, 51, 51, 50, 50, 50,
+	50, 50, 50, 39, 39, 44, 44, 45, 45, 46,
 	22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
-	22, 22, 49, 49, 47, 47, 45, 45, 45, 48,
-	48, 46, 46, 46, 20, 20, 42, 42, 43, 43,
-	44, 41, 41, 50, 52, 52, 52, 51, 51, 51,
-	51, 51, 51, 53, 53, 36, 38, 38, 38, 37,
-	37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
-	37, 37, 54, 56, 56, 56, 55, 55, 55, 55,
-	55, 58, 60, 60, 60, 59, 59, 59, 59, 59,
-	61, 61, 62, 62, 11, 11, 11, 10, 10, 10,
-	10, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+	22, 22, 60, 60, 58, 58, 56, 56, 56, 59,
+	59, 57, 57, 57, 20, 20, 53, 53, 54, 54,
+	55, 52, 52, 61, 63, 63, 63, 62, 62, 62,
+	62, 62, 62, 64, 64, 47, 49, 49, 49, 48,
+	48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+	48, 48, 65, 67, 67, 67, 66, 66, 66, 66,
+	66, 69, 71, 71, 71, 70, 70, 70, 70, 70,
+	72, 72, 73, 73, 11, 11, 11, 10, 10, 10,
+	10, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+	23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+	23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+	23, 23, 23, 23, 24, 24, 24, 24, 24, 24,
+	24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+	24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+	24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+	24, 24, 24, 24, 26, 26, 26, 26, 26, 26,
+	26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+	26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+	26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+	26, 26, 26, 26, 26, 25, 25, 25, 25, 25,
+	25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+	25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+	25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+	25, 25, 25, 25, 21, 21, 21, 21, 21, 21,
 	21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
 	21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
 	21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-	21, 21, 21, 21,
+	21, 21, 21, 21, 21, 21, 21,
 }
 
 var protoR2 = [...]int{
 	0, 1, 1, 2, 0, 2, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 2, 1, 4, 3, 4,
-	4, 3, 1, 3, 5, 1, 3, 1, 3, 1,
-	1, 1, 1, 1, 1, 2, 2, 2, 2, 1,
-	2, 2, 1, 2, 3, 1, 2, 0, 1, 2,
-	2, 2, 2, 1, 3, 4, 5, 5, 3, 2,
-	5, 4, 5, 4, 1, 3, 3, 1, 3, 3,
-	5, 3, 5, 1, 2, 6, 6, 6, 5, 7,
-	7, 7, 6, 3, 1, 3, 3, 8, 8, 8,
+	4, 3, 1, 3, 1, 3, 1, 3, 1, 3,
+	5, 1, 3, 1, 3, 1, 1, 1, 1, 1,
+	1, 2, 2, 2, 2, 1, 2, 2, 1, 2,
+	3, 1, 2, 0, 1, 2, 2, 2, 2, 1,
+	3, 4, 5, 5, 3, 2, 5, 4, 5, 4,
+	1, 3, 3, 1, 3, 3, 5, 3, 5, 1,
+	2, 1, 2, 1, 2, 1, 2, 6, 6, 6,
+	7, 7, 7, 5, 6, 6, 6, 6, 7, 7,
+	7, 5, 6, 3, 1, 3, 3, 8, 8, 8,
 	9, 9, 9, 5, 2, 1, 0, 1, 1, 1,
 	1, 2, 1, 5, 6, 7, 8, 5, 6, 6,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -622,97 +676,150 @@ var protoR2 = [...]int{
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-	1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1,
 }
 
 var protoChk = [...]int{
-	-1000, -1, -2, -4, 8, -3, -5, -6, -7, -36,
-	-50, -54, -58, 52, 2, 9, 12, 13, 44, 43,
-	45, 46, -4, -3, 51, 52, -57, 10, 11, 4,
-	-23, -21, 7, 8, 9, 10, 11, 12, 13, 14,
+	-1000, -1, -2, -4, 8, -3, -5, -6, -7, -47,
+	-61, -65, -69, 52, 2, 9, 12, 13, 44, 43,
+	45, 46, -4, -3, 51, 52, -68, 10, 11, 4,
+	-27, -21, 7, 8, 9, 10, 11, 12, 13, 14,
 	15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
 	25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
 	35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
 	45, 46, 47, 48, 49, -14, -12, -21, 65, -21,
-	-21, -24, -23, 59, -21, -57, 52, -57, -57, -57,
-	52, 59, 51, 59, -24, 54, 54, 54, -23, 54,
-	52, 52, 52, -23, -16, -17, -18, -57, -19, -21,
-	54, 6, 64, 63, 5, -14, 66, -38, -37, -29,
-	-50, -36, -54, -49, -32, -7, -31, -34, -42, 52,
-	2, 20, 19, 18, -24, 43, 44, 45, 39, 13,
-	37, -35, 42, -44, 38, -52, -51, -7, -53, -43,
-	52, 2, -21, 42, -44, -56, -55, -29, -32, 52,
-	2, -60, -59, -7, -61, 52, 2, 47, 52, -28,
-	-27, -26, 2, -13, -21, 67, 6, 16, 5, 6,
-	16, 5, 55, -37, 52, -24, 36, -24, 36, -24,
-	36, -21, -47, -45, 5, -21, -21, -47, -41, -57,
-	62, 55, -51, 52, 51, -48, -46, -20, 5, 64,
-	55, -55, 52, 55, -59, 52, -21, 55, -28, 60,
-	52, 60, 52, 53, -18, 62, -24, 2, -21, -21,
-	-21, -21, -21, -21, 51, 52, -15, 67, 60, 40,
-	54, 51, 52, 52, 60, -22, 23, 24, 25, 26,
-	27, 28, 29, 30, 31, 32, 33, 34, -20, 52,
-	60, 40, 5, -62, 65, -17, 67, -18, 62, -28,
-	2, 68, 68, 51, 51, 51, 51, 51, 51, 5,
-	52, -9, -8, -14, -47, 5, 41, -40, -39, -7,
-	-30, -33, 52, 2, -24, 36, 5, -41, 60, 52,
-	-15, -48, -20, 41, 49, 48, -24, 68, -25, 2,
-	-16, 62, -28, 2, 61, 61, 5, 5, 5, 5,
-	5, 5, 52, -15, 68, 60, 51, 55, -39, 52,
-	-21, -21, 52, -15, -24, 52, -62, -24, 66, 68,
-	68, 60, -28, 2, 61, 61, 52, -15, 54, -15,
-	52, -15, 54, -15, 52, -15, 54, -15, 52, -9,
-	-16, 51, 51, 52, 61, 52, 54, 66, -25, 61,
-	61, 52, -38, 54, 52, -38, 54, 52, -38, 54,
-	5, 5, -11, -10, -7, 52, 2, 60, 60, 55,
-	-38, 55, -38, 55, -38, 52, -15, 54, -15, 55,
-	-10, 52, -25, -25, 55, 55, 55, 52, -38, 54,
-	55, -38, 55,
+	-21, -31, -27, 59, -21, -68, 52, -68, -68, -68,
+	52, 59, 51, 59, -31, 54, 54, 54, -27, 54,
+	52, 52, 52, -27, -16, -17, -18, -68, -19, -21,
+	54, 6, 64, 63, 5, -14, 66, -49, -48, -40,
+	-61, -47, -65, -60, -43, -7, -42, -45, -53, 52,
+	2, 20, 19, 18, -32, 39, 37, -46, 42, -55,
+	-28, 59, 38, -23, 7, 8, 9, 10, 11, 12,
+	14, 15, 16, 17, 21, 22, 23, 24, 25, 26,
+	27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+	40, 41, 46, 47, 48, 49, -63, -62, -7, -64,
+	-54, 52, 2, -26, 42, -55, 7, 8, 9, 10,
+	11, 12, 14, 15, 16, 17, 18, 19, 20, 21,
+	22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+	32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+	43, 44, 45, 46, 47, 48, 49, -67, -66, -41,
+	-43, 52, 2, 20, 19, 18, -33, -29, 59, -24,
+	7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+	17, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+	30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+	40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+	-71, -70, -7, -72, 52, 2, 47, 52, -38, -37,
+	-36, 2, -13, -21, 67, 6, 16, 5, 6, 16,
+	5, 55, -48, 52, -31, 36, -31, 36, -31, 36,
+	-21, -58, -56, 5, -21, -21, -58, -52, -68, -27,
+	62, 59, 55, -62, 52, 51, -59, -57, -20, 5,
+	64, 55, -66, 52, -31, -31, -31, -21, -27, 59,
+	55, -70, 52, -21, 55, -38, 60, 52, 60, 52,
+	53, -18, 62, -31, 2, -21, -21, -21, -21, -21,
+	-21, 51, 52, -15, 67, 60, 40, 54, 51, 52,
+	52, 60, -22, 23, 24, 25, 26, 27, 28, 29,
+	30, 31, 32, 33, 34, -27, -20, 52, 60, 40,
+	5, -21, -21, -21, 51, -27, -73, 65, -17, 67,
+	-18, 62, -38, 2, 68, 68, 51, 51, 51, 51,
+	51, 51, 5, 52, -9, -8, -14, -58, 5, 41,
+	-51, -50, -7, -39, -44, 52, 2, -34, 36, -30,
+	59, -25, 7, 8, 9, 10, 11, 12, 14, 15,
+	16, 17, 21, 22, 23, 24, 25, 26, 27, 28,
+	29, 30, 31, 32, 33, 34, 35, 37, 38, 39,
+	40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+	5, -52, 60, 52, -15, -59, -20, 41, 51, 51,
+	51, 5, 49, 48, -31, 68, -35, 2, -16, 62,
+	-38, 2, 61, 61, 5, 5, 5, 5, 5, 5,
+	52, -15, 68, 60, 51, 55, -50, 52, -21, -21,
+	-27, 59, 52, -15, -31, 52, 5, 5, 5, 52,
+	-15, -73, -31, 66, 68, 68, 60, -38, 2, 61,
+	61, 52, -15, 54, -15, 52, -15, 54, -15, 52,
+	-15, 54, -15, 52, -9, -16, 51, 51, -27, 52,
+	61, 52, -15, 52, -15, 52, -15, 52, 52, 54,
+	66, -35, 61, 61, 52, -49, 54, 52, -49, 54,
+	52, -49, 54, 5, 5, 52, 52, 52, -11, -10,
+	-7, 52, 2, 60, 60, 55, -49, 55, -49, 55,
+	-49, 52, -15, 54, -15, 55, -10, 52, -35, -35,
+	55, 55, 55, 52, -49, 54, 55, -49, 55,
 }
 
 var protoDef = [...]int{
 	-2, -2, -2, -2, 0, 6, 7, 8, 9, 10,
 	11, 12, 13, 14, 16, 0, 0, 0, 0, 0,
-	0, 0, -2, 5, 0, 15, 0, 0, 0, 42,
-	0, 22, 201, 202, 203, 204, 205, 206, 207, 208,
-	209, 210, 211, 212, 213, 214, 215, 216, 217, 218,
-	219, 220, 221, 222, 223, 224, 225, 226, 227, 228,
-	229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
-	239, 240, 241, 242, 243, 0, 25, 27, 0, 0,
-	0, 0, 73, 0, 0, 0, 18, 0, 0, 43,
-	21, 0, 0, 0, 0, -2, -2, -2, 74, -2,
-	17, 19, 20, 23, 0, 29, 30, 31, 32, 33,
-	-2, 34, 0, 0, 39, 26, 28, 0, 157, 159,
-	160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
-	171, 0, 0, 0, 0, 237, 238, 0, 233, 207,
-	231, 0, 236, 137, 232, 0, 145, 147, 148, 149,
-	150, 152, 0, 236, 139, 0, 174, 176, 177, 178,
-	180, 0, 183, 185, 186, 187, 189, 0, 24, 0,
-	-2, 48, 53, 0, 64, 0, 35, 38, 41, 36,
-	37, 40, 155, 156, 170, 0, 230, 0, 230, 0,
-	230, 0, 0, 124, 126, 0, 0, 0, 0, 141,
-	0, 143, 144, 151, 0, 0, 129, 131, 134, 0,
-	172, 173, 179, 181, 182, 188, 0, 44, 46, 49,
-	50, 51, 52, 0, 59, -2, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 122, 0, 0, 0, 0,
-	-2, 0, 136, 140, 0, 0, 110, 111, 112, 113,
-	114, 115, 116, 117, 118, 119, 120, 121, 0, 138,
-	0, 0, 135, 0, 0, 54, 0, 58, -2, 0,
-	53, 65, 66, 0, 0, 0, 0, 0, 0, 0,
-	123, 0, 84, 0, 125, 127, 128, 0, 95, 97,
-	98, 99, 100, 102, 0, 230, 0, 142, 0, 153,
-	0, 130, 132, 133, 0, 242, 0, 55, 0, 0,
-	67, -2, 0, 53, 61, 63, 0, 0, 0, 0,
-	0, 0, 78, 0, 83, 0, 0, 93, 94, 101,
-	0, 0, 107, 0, 0, 154, 0, 0, 193, 56,
-	57, 0, 0, 53, 60, 62, 75, 0, -2, 0,
-	76, 0, -2, 0, 77, 0, -2, 0, 82, 85,
-	86, 0, 0, 108, 109, 190, -2, 192, 68, 69,
-	71, 79, 0, -2, 80, 0, -2, 81, 0, -2,
-	0, 0, 0, 195, 197, 198, 200, 0, 0, 87,
-	0, 88, 0, 89, 0, 103, 0, -2, 0, 191,
-	194, 199, 70, 72, 90, 91, 92, 104, 0, -2,
-	105, 0, 106,
+	0, 0, -2, 5, 0, 15, 0, 0, 0, 48,
+	0, 22, 374, 375, 376, 377, 378, 379, 380, 381,
+	382, 383, 384, 385, 386, 387, 388, 389, 390, 391,
+	392, 393, 394, 395, 396, 397, 398, 399, 400, 401,
+	402, 403, 404, 405, 406, 407, 408, 409, 410, 411,
+	412, 413, 414, 415, 416, 0, 31, 33, 0, 0,
+	0, 0, 79, 0, 0, 0, 18, 0, 0, 49,
+	21, 0, 0, 0, 0, -2, -2, -2, 80, -2,
+	17, 19, 20, 23, 0, 35, 36, 37, 38, 39,
+	-2, 40, 0, 0, 45, 32, 34, 0, 177, 179,
+	180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
+	191, 0, 0, 0, 0, 0, 0, 0, 0, 157,
+	81, 0, 247, 24, 221, 222, 223, 224, 225, 226,
+	227, 228, 229, 230, 231, 232, 233, 234, 235, 236,
+	237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
+	248, 249, 250, 251, 252, 253, 0, 165, 167, 168,
+	169, 170, 172, 0, 0, 159, 294, 295, 296, 297,
+	298, 299, 300, 301, 302, 303, 304, 305, 306, 307,
+	308, 309, 310, 311, 312, 313, 314, 315, 316, 317,
+	318, 319, 320, 321, 322, 323, 324, 325, 326, 327,
+	328, 329, 330, 331, 332, 333, 334, 0, 194, 196,
+	197, 198, 200, 0, 0, 0, 0, 83, 0, 26,
+	254, 255, 256, 257, 258, 259, 260, 261, 262, 263,
+	264, 265, 266, 267, 268, 269, 270, 271, 272, 273,
+	274, 275, 276, 277, 278, 279, 280, 281, 282, 283,
+	284, 285, 286, 287, 288, 289, 290, 291, 292, 293,
+	0, 203, 205, 206, 207, 209, 0, 30, 0, -2,
+	54, 59, 0, 70, 0, 41, 44, 47, 42, 43,
+	46, 175, 176, 190, 0, 403, 0, 403, 0, 403,
+	0, 0, 144, 146, 0, 0, 0, 0, 161, 82,
+	0, 0, 163, 164, 171, 0, 0, 149, 151, 154,
+	0, 192, 193, 199, 0, 0, 0, 0, 84, 0,
+	201, 202, 208, 0, 50, 52, 55, 56, 57, 58,
+	0, 65, -2, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 142, 0, 0, 0, 0, -2, 0, 156,
+	160, 0, 0, 130, 131, 132, 133, 134, 135, 136,
+	137, 138, 139, 140, 141, 25, 0, 158, 0, 0,
+	155, 0, 0, 0, 0, 27, 0, 0, 60, 0,
+	64, -2, 0, 59, 71, 72, 0, 0, 0, 0,
+	0, 0, 0, 143, 0, 104, 0, 145, 147, 148,
+	0, 115, 117, 118, 119, 120, 122, 0, 360, 85,
+	0, 28, 335, 336, 337, 338, 339, 340, 341, 342,
+	343, 344, 345, 346, 347, 348, 349, 350, 351, 352,
+	353, 354, 355, 356, 357, 358, 359, 361, 362, 363,
+	364, 365, 366, 367, 368, 369, 370, 371, 372, 373,
+	0, 162, 0, 173, 0, 150, 152, 153, 0, 0,
+	0, 0, 0, 415, 0, 61, 0, 0, 73, -2,
+	0, 59, 67, 69, 0, 0, 0, 0, 0, 0,
+	93, 0, 103, 0, 0, 113, 114, 121, 0, 0,
+	86, 0, 127, 0, 0, 174, 0, 0, 0, 101,
+	0, 0, 0, 213, 62, 63, 0, 0, 59, 66,
+	68, 87, 0, -2, 0, 88, 0, -2, 0, 89,
+	0, -2, 0, 94, 105, 106, 0, 0, 29, 128,
+	129, 95, 0, 96, 0, 97, 0, 102, 210, -2,
+	212, 74, 75, 77, 90, 0, -2, 91, 0, -2,
+	92, 0, -2, 0, 0, 98, 99, 100, 0, 215,
+	217, 218, 220, 0, 0, 107, 0, 108, 0, 109,
+	0, 123, 0, -2, 0, 211, 214, 219, 76, 78,
+	110, 111, 112, 124, 0, -2, 125, 0, 126,
 }
 
 var protoTok1 = [...]int{
@@ -1229,46 +1336,82 @@ protodefault:
 			protoVAL.cid = &identList{protoDollar[1].id, protoDollar[2].b, protoDollar[3].cid}
 		}
 	case 24:
+		protoDollar = protoS[protopt-1 : protopt+1]
+//line proto.y:233
+		{
+			protoVAL.cid = &identList{protoDollar[1].id, nil, nil}
+		}
+	case 25:
+		protoDollar = protoS[protopt-3 : protopt+1]
+//line proto.y:236
+		{
+			protoVAL.cid = &identList{protoDollar[1].id, protoDollar[2].b, protoDollar[3].cid}
+		}
+	case 26:
+		protoDollar = protoS[protopt-1 : protopt+1]
+//line proto.y:240
+		{
+			protoVAL.cid = &identList{protoDollar[1].id, nil, nil}
+		}
+	case 27:
+		protoDollar = protoS[protopt-3 : protopt+1]
+//line proto.y:243
+		{
+			protoVAL.cid = &identList{protoDollar[1].id, protoDollar[2].b, protoDollar[3].cid}
+		}
+	case 28:
+		protoDollar = protoS[protopt-1 : protopt+1]
+//line proto.y:247
+		{
+			protoVAL.cid = &identList{protoDollar[1].id, nil, nil}
+		}
+	case 29:
+		protoDollar = protoS[protopt-3 : protopt+1]
+//line proto.y:250
+		{
+			protoVAL.cid = &identList{protoDollar[1].id, protoDollar[2].b, protoDollar[3].cid}
+		}
+	case 30:
 		protoDollar = protoS[protopt-5 : protopt+1]
-//line proto.y:229
+//line proto.y:254
 		{
 			refs, dots := protoDollar[2].optNms.toNodes()
 			optName := ast.NewOptionNameNode(refs, dots)
 			protoVAL.opt = ast.NewOptionNode(protoDollar[1].id.ToKeyword(), optName, protoDollar[3].b, protoDollar[4].v, protoDollar[5].b)
 		}
-	case 25:
+	case 31:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:235
+//line proto.y:260
 		{
 			protoVAL.optNms = &fieldRefList{protoDollar[1].ref, nil, nil}
 		}
-	case 26:
+	case 32:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:238
+//line proto.y:263
 		{
 			protoVAL.optNms = &fieldRefList{protoDollar[1].ref, protoDollar[2].b, protoDollar[3].optNms}
 		}
-	case 27:
+	case 33:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:242
+//line proto.y:267
 		{
 			protoVAL.ref = ast.NewFieldReferenceNode(protoDollar[1].id)
 		}
-	case 28:
+	case 34:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:245
+//line proto.y:270
 		{
 			protoVAL.ref = ast.NewExtensionFieldReferenceNode(protoDollar[1].b, protoDollar[2].tid, protoDollar[3].b)
 		}
-	case 31:
+	case 37:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:252
+//line proto.y:277
 		{
 			protoVAL.v = protoDollar[1].str.toStringValueNode()
 		}
-	case 33:
+	case 39:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:256
+//line proto.y:281
 		{
 			if protoDollar[1].id.Val == "true" || protoDollar[1].id.Val == "false" {
 				protoVAL.v = ast.NewBoolLiteralNode(protoDollar[1].id.ToKeyword())
@@ -1278,53 +1421,53 @@ protodefault:
 				protoVAL.v = protoDollar[1].id
 			}
 		}
-	case 34:
+	case 40:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:266
+//line proto.y:291
 		{
 			protoVAL.v = protoDollar[1].f
 		}
-	case 35:
+	case 41:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:269
+//line proto.y:294
 		{
 			protoVAL.v = ast.NewSignedFloatLiteralNode(protoDollar[1].b, protoDollar[2].f)
 		}
-	case 36:
+	case 42:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:272
+//line proto.y:297
 		{
 			protoVAL.v = ast.NewSignedFloatLiteralNode(protoDollar[1].b, protoDollar[2].f)
 		}
-	case 37:
+	case 43:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:275
+//line proto.y:300
 		{
 			f := ast.NewSpecialFloatLiteralNode(protoDollar[2].id.ToKeyword())
 			protoVAL.v = ast.NewSignedFloatLiteralNode(protoDollar[1].b, f)
 		}
-	case 38:
+	case 44:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:279
+//line proto.y:304
 		{
 			f := ast.NewSpecialFloatLiteralNode(protoDollar[2].id.ToKeyword())
 			protoVAL.v = ast.NewSignedFloatLiteralNode(protoDollar[1].b, f)
 		}
-	case 39:
+	case 45:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:283
+//line proto.y:308
 		{
 			protoVAL.v = protoDollar[1].i
 		}
-	case 40:
+	case 46:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:286
+//line proto.y:311
 		{
 			protoVAL.v = ast.NewPositiveUintLiteralNode(protoDollar[1].b, protoDollar[2].i)
 		}
-	case 41:
+	case 47:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:289
+//line proto.y:314
 		{
 			if protoDollar[2].i.Val > math.MaxInt64+1 {
 				// can't represent as int so treat as float literal
@@ -1333,28 +1476,28 @@ protodefault:
 				protoVAL.v = ast.NewNegativeIntLiteralNode(protoDollar[1].b, protoDollar[2].i)
 			}
 		}
-	case 42:
+	case 48:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:298
+//line proto.y:323
 		{
 			protoVAL.str = &stringList{protoDollar[1].s, nil}
 		}
-	case 43:
+	case 49:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:301
+//line proto.y:326
 		{
 			protoVAL.str = &stringList{protoDollar[1].s, protoDollar[2].str}
 		}
-	case 44:
+	case 50:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:305
+//line proto.y:330
 		{
 			fields, delims := protoDollar[2].msgLit.toNodes()
 			protoVAL.v = ast.NewMessageLiteralNode(protoDollar[1].b, fields, delims, protoDollar[3].b)
 		}
-	case 45:
+	case 51:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:310
+//line proto.y:335
 		{
 			if protoDollar[1].msgEntry != nil {
 				protoVAL.msgLit = &messageFieldList{protoDollar[1].msgEntry, nil}
@@ -1362,9 +1505,9 @@ protodefault:
 				protoVAL.msgLit = nil
 			}
 		}
-	case 46:
+	case 52:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:317
+//line proto.y:342
 		{
 			if protoDollar[1].msgEntry != nil {
 				protoVAL.msgLit = &messageFieldList{protoDollar[1].msgEntry, protoDollar[2].msgLit}
@@ -1372,15 +1515,15 @@ protodefault:
 				protoVAL.msgLit = protoDollar[2].msgLit
 			}
 		}
-	case 47:
+	case 53:
 		protoDollar = protoS[protopt-0 : protopt+1]
-//line proto.y:324
+//line proto.y:349
 		{
 			protoVAL.msgLit = nil
 		}
-	case 48:
+	case 54:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:328
+//line proto.y:353
 		{
 			if protoDollar[1].msgField != nil {
 				protoVAL.msgEntry = &messageFieldEntry{protoDollar[1].msgField, nil}
@@ -1388,9 +1531,9 @@ protodefault:
 				protoVAL.msgEntry = nil
 			}
 		}
-	case 49:
+	case 55:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:335
+//line proto.y:360
 		{
 			if protoDollar[1].msgField != nil {
 				protoVAL.msgEntry = &messageFieldEntry{protoDollar[1].msgField, protoDollar[2].b}
@@ -1398,9 +1541,9 @@ protodefault:
 				protoVAL.msgEntry = nil
 			}
 		}
-	case 50:
+	case 56:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:342
+//line proto.y:367
 		{
 			if protoDollar[1].msgField != nil {
 				protoVAL.msgEntry = &messageFieldEntry{protoDollar[1].msgField, protoDollar[2].b}
@@ -1408,27 +1551,27 @@ protodefault:
 				protoVAL.msgEntry = nil
 			}
 		}
-	case 51:
+	case 57:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:349
+//line proto.y:374
 		{
 			protoVAL.msgEntry = nil
 		}
-	case 52:
+	case 58:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:352
+//line proto.y:377
 		{
 			protoVAL.msgEntry = nil
 		}
-	case 53:
+	case 59:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:355
+//line proto.y:380
 		{
 			protoVAL.msgEntry = nil
 		}
-	case 54:
+	case 60:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:359
+//line proto.y:384
 		{
 			if protoDollar[1].ref != nil {
 				protoVAL.msgField = ast.NewMessageFieldNode(protoDollar[1].ref, protoDollar[2].b, protoDollar[3].v)
@@ -1436,9 +1579,9 @@ protodefault:
 				protoVAL.msgField = nil
 			}
 		}
-	case 55:
+	case 61:
 		protoDollar = protoS[protopt-4 : protopt+1]
-//line proto.y:366
+//line proto.y:391
 		{
 			if protoDollar[1].ref != nil {
 				val := ast.NewArrayLiteralNode(protoDollar[3].b, nil, nil, protoDollar[4].b)
@@ -1447,9 +1590,9 @@ protodefault:
 				protoVAL.msgField = nil
 			}
 		}
-	case 56:
+	case 62:
 		protoDollar = protoS[protopt-5 : protopt+1]
-//line proto.y:374
+//line proto.y:399
 		{
 			if protoDollar[1].ref != nil {
 				vals, commas := protoDollar[4].sl.toNodes()
@@ -1459,15 +1602,15 @@ protodefault:
 				protoVAL.msgField = nil
 			}
 		}
-	case 57:
+	case 63:
 		protoDollar = protoS[protopt-5 : protopt+1]
-//line proto.y:383
+//line proto.y:408
 		{
 			protoVAL.msgField = nil
 		}
-	case 58:
+	case 64:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:386
+//line proto.y:411
 		{
 			if protoDollar[1].ref != nil {
 				protoVAL.msgField = ast.NewMessageFieldNode(protoDollar[1].ref, protoDollar[2].b, protoDollar[3].v)
@@ -1475,9 +1618,9 @@ protodefault:
 				protoVAL.msgField = nil
 			}
 		}
-	case 59:
+	case 65:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:393
+//line proto.y:418
 		{
 			if protoDollar[1].ref != nil {
 				protoVAL.msgField = ast.NewMessageFieldNode(protoDollar[1].ref, nil, protoDollar[2].v)
@@ -1485,9 +1628,9 @@ protodefault:
 				protoVAL.msgField = nil
 			}
 		}
-	case 60:
+	case 66:
 		protoDollar = protoS[protopt-5 : protopt+1]
-//line proto.y:400
+//line proto.y:425
 		{
 			if protoDollar[1].ref != nil {
 				fields, delims := protoDollar[4].msgLit.toNodes()
@@ -1497,9 +1640,9 @@ protodefault:
 				protoVAL.msgField = nil
 			}
 		}
-	case 61:
+	case 67:
 		protoDollar = protoS[protopt-4 : protopt+1]
-//line proto.y:409
+//line proto.y:434
 		{
 			if protoDollar[1].ref != nil {
 				fields, delims := protoDollar[3].msgLit.toNodes()
@@ -1509,208 +1652,292 @@ protodefault:
 				protoVAL.msgField = nil
 			}
 		}
-	case 62:
+	case 68:
 		protoDollar = protoS[protopt-5 : protopt+1]
-//line proto.y:418
+//line proto.y:443
 		{
 			protoVAL.msgField = nil
 		}
-	case 63:
+	case 69:
 		protoDollar = protoS[protopt-4 : protopt+1]
-//line proto.y:421
+//line proto.y:446
 		{
 			protoVAL.msgField = nil
 		}
-	case 64:
+	case 70:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:425
+//line proto.y:450
 		{
 			protoVAL.ref = ast.NewFieldReferenceNode(protoDollar[1].id)
 		}
-	case 65:
+	case 71:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:428
+//line proto.y:453
 		{
 			protoVAL.ref = ast.NewExtensionFieldReferenceNode(protoDollar[1].b, protoDollar[2].tid, protoDollar[3].b)
 		}
-	case 66:
+	case 72:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:431
+//line proto.y:456
 		{
 			protoVAL.ref = nil
 		}
-	case 67:
+	case 73:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:435
+//line proto.y:460
 		{
 			protoVAL.sl = &valueList{protoDollar[1].v, nil, nil}
 		}
-	case 68:
+	case 74:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:438
+//line proto.y:463
 		{
 			protoVAL.sl = &valueList{protoDollar[1].v, protoDollar[2].b, protoDollar[3].sl}
 		}
-	case 69:
+	case 75:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:441
+//line proto.y:466
 		{
 			fields, delims := protoDollar[2].msgLit.toNodes()
 			msg := ast.NewMessageLiteralNode(protoDollar[1].b, fields, delims, protoDollar[3].b)
 			protoVAL.sl = &valueList{msg, nil, nil}
 		}
-	case 70:
+	case 76:
 		protoDollar = protoS[protopt-5 : protopt+1]
-//line proto.y:446
+//line proto.y:471
 		{
 			fields, delims := protoDollar[2].msgLit.toNodes()
 			msg := ast.NewMessageLiteralNode(protoDollar[1].b, fields, delims, protoDollar[3].b)
 			protoVAL.sl = &valueList{msg, protoDollar[4].b, protoDollar[5].sl}
 		}
-	case 71:
+	case 77:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:451
+//line proto.y:476
 		{
 			protoVAL.sl = nil
 		}
-	case 72:
+	case 78:
 		protoDollar = protoS[protopt-5 : protopt+1]
-//line proto.y:454
+//line proto.y:479
 		{
 			protoVAL.sl = protoDollar[5].sl
 		}
-	case 73:
+	case 79:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:458
+//line proto.y:483
 		{
 			protoVAL.tid = protoDollar[1].cid.toIdentValueNode(nil)
 		}
-	case 74:
+	case 80:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:461
+//line proto.y:486
 		{
 			protoVAL.tid = protoDollar[2].cid.toIdentValueNode(protoDollar[1].b)
 		}
-	case 75:
-		protoDollar = protoS[protopt-6 : protopt+1]
-//line proto.y:465
-		{
+	case 81:
+		protoDollar = protoS[protopt-1 : protopt+1]
+//line proto.y:490
+		{
+			protoVAL.tid = protoDollar[1].cid.toIdentValueNode(nil)
+		}
+	case 82:
+		protoDollar = protoS[protopt-2 : protopt+1]
+//line proto.y:493
+		{
+			protoVAL.tid = protoDollar[2].cid.toIdentValueNode(protoDollar[1].b)
+		}
+	case 83:
+		protoDollar = protoS[protopt-1 : protopt+1]
+//line proto.y:497
+		{
+			protoVAL.tid = protoDollar[1].cid.toIdentValueNode(nil)
+		}
+	case 84:
+		protoDollar = protoS[protopt-2 : protopt+1]
+//line proto.y:500
+		{
+			protoVAL.tid = protoDollar[2].cid.toIdentValueNode(protoDollar[1].b)
+		}
+	case 85:
+		protoDollar = protoS[protopt-1 : protopt+1]
+//line proto.y:504
+		{
+			protoVAL.tid = protoDollar[1].cid.toIdentValueNode(nil)
+		}
+	case 86:
+		protoDollar = protoS[protopt-2 : protopt+1]
+//line proto.y:507
+		{
+			protoVAL.tid = protoDollar[2].cid.toIdentValueNode(protoDollar[1].b)
+		}
+	case 87:
+		protoDollar = protoS[protopt-6 : protopt+1]
+//line proto.y:511
+		{
 			protoVAL.fld = ast.NewFieldNode(protoDollar[1].id.ToKeyword(), protoDollar[2].tid, protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, nil, protoDollar[6].b)
 		}
-	case 76:
+	case 88:
 		protoDollar = protoS[protopt-6 : protopt+1]
-//line proto.y:468
+//line proto.y:514
 		{
 			protoVAL.fld = ast.NewFieldNode(protoDollar[1].id.ToKeyword(), protoDollar[2].tid, protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, nil, protoDollar[6].b)
 		}
-	case 77:
+	case 89:
 		protoDollar = protoS[protopt-6 : protopt+1]
-//line proto.y:471
+//line proto.y:517
 		{
 			protoVAL.fld = ast.NewFieldNode(protoDollar[1].id.ToKeyword(), protoDollar[2].tid, protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, nil, protoDollar[6].b)
 		}
-	case 78:
+	case 90:
+		protoDollar = protoS[protopt-7 : protopt+1]
+//line proto.y:520
+		{
+			protoVAL.fld = ast.NewFieldNode(protoDollar[1].id.ToKeyword(), protoDollar[2].tid, protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, protoDollar[6].cmpctOpts, protoDollar[7].b)
+		}
+	case 91:
+		protoDollar = protoS[protopt-7 : protopt+1]
+//line proto.y:523
+		{
+			protoVAL.fld = ast.NewFieldNode(protoDollar[1].id.ToKeyword(), protoDollar[2].tid, protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, protoDollar[6].cmpctOpts, protoDollar[7].b)
+		}
+	case 92:
+		protoDollar = protoS[protopt-7 : protopt+1]
+//line proto.y:526
+		{
+			protoVAL.fld = ast.NewFieldNode(protoDollar[1].id.ToKeyword(), protoDollar[2].tid, protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, protoDollar[6].cmpctOpts, protoDollar[7].b)
+		}
+	case 93:
 		protoDollar = protoS[protopt-5 : protopt+1]
-//line proto.y:474
+//line proto.y:529
 		{
 			protoVAL.fld = ast.NewFieldNode(nil, protoDollar[1].tid, protoDollar[2].id, protoDollar[3].b, protoDollar[4].i, nil, protoDollar[5].b)
 		}
-	case 79:
+	case 94:
+		protoDollar = protoS[protopt-6 : protopt+1]
+//line proto.y:532
+		{
+			protoVAL.fld = ast.NewFieldNode(nil, protoDollar[1].tid, protoDollar[2].id, protoDollar[3].b, protoDollar[4].i, protoDollar[5].cmpctOpts, protoDollar[6].b)
+		}
+	case 95:
+		protoDollar = protoS[protopt-6 : protopt+1]
+//line proto.y:536
+		{
+			protoVAL.fld = ast.NewFieldNode(protoDollar[1].id.ToKeyword(), protoDollar[2].tid, protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, nil, protoDollar[6].b)
+		}
+	case 96:
+		protoDollar = protoS[protopt-6 : protopt+1]
+//line proto.y:539
+		{
+			protoVAL.fld = ast.NewFieldNode(protoDollar[1].id.ToKeyword(), protoDollar[2].tid, protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, nil, protoDollar[6].b)
+		}
+	case 97:
+		protoDollar = protoS[protopt-6 : protopt+1]
+//line proto.y:542
+		{
+			protoVAL.fld = ast.NewFieldNode(protoDollar[1].id.ToKeyword(), protoDollar[2].tid, protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, nil, protoDollar[6].b)
+		}
+	case 98:
 		protoDollar = protoS[protopt-7 : protopt+1]
-//line proto.y:477
+//line proto.y:545
 		{
 			protoVAL.fld = ast.NewFieldNode(protoDollar[1].id.ToKeyword(), protoDollar[2].tid, protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, protoDollar[6].cmpctOpts, protoDollar[7].b)
 		}
-	case 80:
+	case 99:
 		protoDollar = protoS[protopt-7 : protopt+1]
-//line proto.y:480
+//line proto.y:548
 		{
 			protoVAL.fld = ast.NewFieldNode(protoDollar[1].id.ToKeyword(), protoDollar[2].tid, protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, protoDollar[6].cmpctOpts, protoDollar[7].b)
 		}
-	case 81:
+	case 100:
 		protoDollar = protoS[protopt-7 : protopt+1]
-//line proto.y:483
+//line proto.y:551
 		{
 			protoVAL.fld = ast.NewFieldNode(protoDollar[1].id.ToKeyword(), protoDollar[2].tid, protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, protoDollar[6].cmpctOpts, protoDollar[7].b)
 		}
-	case 82:
+	case 101:
+		protoDollar = protoS[protopt-5 : protopt+1]
+//line proto.y:554
+		{
+			protoVAL.fld = ast.NewFieldNode(nil, protoDollar[1].tid, protoDollar[2].id, protoDollar[3].b, protoDollar[4].i, nil, protoDollar[5].b)
+		}
+	case 102:
 		protoDollar = protoS[protopt-6 : protopt+1]
-//line proto.y:486
+//line proto.y:557
 		{
 			protoVAL.fld = ast.NewFieldNode(nil, protoDollar[1].tid, protoDollar[2].id, protoDollar[3].b, protoDollar[4].i, protoDollar[5].cmpctOpts, protoDollar[6].b)
 		}
-	case 83:
+	case 103:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:490
+//line proto.y:561
 		{
 			opts, commas := protoDollar[2].opts.toNodes()
 			protoVAL.cmpctOpts = ast.NewCompactOptionsNode(protoDollar[1].b, opts, commas, protoDollar[3].b)
 		}
-	case 84:
+	case 104:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:495
+//line proto.y:566
 		{
 			protoVAL.opts = &compactOptionList{protoDollar[1].opt, nil, nil}
 		}
-	case 85:
+	case 105:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:498
+//line proto.y:569
 		{
 			protoVAL.opts = &compactOptionList{protoDollar[1].opt, protoDollar[2].b, protoDollar[3].opts}
 		}
-	case 86:
+	case 106:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:502
+//line proto.y:573
 		{
 			refs, dots := protoDollar[1].optNms.toNodes()
 			optName := ast.NewOptionNameNode(refs, dots)
 			protoVAL.opt = ast.NewCompactOptionNode(optName, protoDollar[2].b, protoDollar[3].v)
 		}
-	case 87:
+	case 107:
 		protoDollar = protoS[protopt-8 : protopt+1]
-//line proto.y:508
+//line proto.y:579
 		{
 			protoVAL.grp = ast.NewGroupNode(protoDollar[1].id.ToKeyword(), protoDollar[2].id.ToKeyword(), protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, nil, protoDollar[6].b, protoDollar[7].msgDecls, protoDollar[8].b)
 		}
-	case 88:
+	case 108:
 		protoDollar = protoS[protopt-8 : protopt+1]
-//line proto.y:511
+//line proto.y:582
 		{
 			protoVAL.grp = ast.NewGroupNode(protoDollar[1].id.ToKeyword(), protoDollar[2].id.ToKeyword(), protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, nil, protoDollar[6].b, protoDollar[7].msgDecls, protoDollar[8].b)
 		}
-	case 89:
+	case 109:
 		protoDollar = protoS[protopt-8 : protopt+1]
-//line proto.y:514
+//line proto.y:585
 		{
 			protoVAL.grp = ast.NewGroupNode(protoDollar[1].id.ToKeyword(), protoDollar[2].id.ToKeyword(), protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, nil, protoDollar[6].b, protoDollar[7].msgDecls, protoDollar[8].b)
 		}
-	case 90:
+	case 110:
 		protoDollar = protoS[protopt-9 : protopt+1]
-//line proto.y:517
+//line proto.y:588
 		{
 			protoVAL.grp = ast.NewGroupNode(protoDollar[1].id.ToKeyword(), protoDollar[2].id.ToKeyword(), protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, protoDollar[6].cmpctOpts, protoDollar[7].b, protoDollar[8].msgDecls, protoDollar[9].b)
 		}
-	case 91:
+	case 111:
 		protoDollar = protoS[protopt-9 : protopt+1]
-//line proto.y:520
+//line proto.y:591
 		{
 			protoVAL.grp = ast.NewGroupNode(protoDollar[1].id.ToKeyword(), protoDollar[2].id.ToKeyword(), protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, protoDollar[6].cmpctOpts, protoDollar[7].b, protoDollar[8].msgDecls, protoDollar[9].b)
 		}
-	case 92:
+	case 112:
 		protoDollar = protoS[protopt-9 : protopt+1]
-//line proto.y:523
+//line proto.y:594
 		{
 			protoVAL.grp = ast.NewGroupNode(protoDollar[1].id.ToKeyword(), protoDollar[2].id.ToKeyword(), protoDollar[3].id, protoDollar[4].b, protoDollar[5].i, protoDollar[6].cmpctOpts, protoDollar[7].b, protoDollar[8].msgDecls, protoDollar[9].b)
 		}
-	case 93:
+	case 113:
 		protoDollar = protoS[protopt-5 : protopt+1]
-//line proto.y:527
+//line proto.y:598
 		{
 			protoVAL.oo = ast.NewOneOfNode(protoDollar[1].id.ToKeyword(), protoDollar[2].id, protoDollar[3].b, protoDollar[4].ooDecls, protoDollar[5].b)
 		}
-	case 94:
+	case 114:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:531
+//line proto.y:602
 		{
 			if protoDollar[2].ooDecl != nil {
 				protoVAL.ooDecls = append(protoDollar[1].ooDecls, protoDollar[2].ooDecl)
@@ -1718,9 +1945,9 @@ protodefault:
 				protoVAL.ooDecls = protoDollar[1].ooDecls
 			}
 		}
-	case 95:
+	case 115:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:538
+//line proto.y:609
 		{
 			if protoDollar[1].ooDecl != nil {
 				protoVAL.ooDecls = []ast.OneOfElement{protoDollar[1].ooDecl}
@@ -1728,218 +1955,218 @@ protodefault:
 				protoVAL.ooDecls = nil
 			}
 		}
-	case 96:
+	case 116:
 		protoDollar = protoS[protopt-0 : protopt+1]
-//line proto.y:545
+//line proto.y:616
 		{
 			protoVAL.ooDecls = nil
 		}
-	case 97:
+	case 117:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:549
+//line proto.y:620
 		{
 			protoVAL.ooDecl = protoDollar[1].opt
 		}
-	case 98:
+	case 118:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:552
+//line proto.y:623
 		{
 			protoVAL.ooDecl = protoDollar[1].fld
 		}
-	case 99:
+	case 119:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:555
+//line proto.y:626
 		{
 			protoVAL.ooDecl = protoDollar[1].grp
 		}
-	case 100:
+	case 120:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:558
+//line proto.y:629
 		{
 			protoVAL.ooDecl = ast.NewEmptyDeclNode(protoDollar[1].b)
 		}
-	case 101:
+	case 121:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:561
+//line proto.y:632
 		{
 			protoVAL.ooDecl = nil
 		}
-	case 102:
+	case 122:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:564
+//line proto.y:635
 		{
 			protoVAL.ooDecl = nil
 		}
-	case 103:
+	case 123:
 		protoDollar = protoS[protopt-5 : protopt+1]
-//line proto.y:568
+//line proto.y:639
 		{
 			protoVAL.fld = ast.NewFieldNode(nil, protoDollar[1].tid, protoDollar[2].id, protoDollar[3].b, protoDollar[4].i, nil, protoDollar[5].b)
 		}
-	case 104:
+	case 124:
 		protoDollar = protoS[protopt-6 : protopt+1]
-//line proto.y:571
+//line proto.y:642
 		{
 			protoVAL.fld = ast.NewFieldNode(nil, protoDollar[1].tid, protoDollar[2].id, protoDollar[3].b, protoDollar[4].i, protoDollar[5].cmpctOpts, protoDollar[6].b)
 		}
-	case 105:
+	case 125:
 		protoDollar = protoS[protopt-7 : protopt+1]
-//line proto.y:575
+//line proto.y:646
 		{
 			protoVAL.grp = ast.NewGroupNode(nil, protoDollar[1].id.ToKeyword(), protoDollar[2].id, protoDollar[3].b, protoDollar[4].i, nil, protoDollar[5].b, protoDollar[6].msgDecls, protoDollar[7].b)
 		}
-	case 106:
+	case 126:
 		protoDollar = protoS[protopt-8 : protopt+1]
-//line proto.y:578
+//line proto.y:649
 		{
 			protoVAL.grp = ast.NewGroupNode(nil, protoDollar[1].id.ToKeyword(), protoDollar[2].id, protoDollar[3].b, protoDollar[4].i, protoDollar[5].cmpctOpts, protoDollar[6].b, protoDollar[7].msgDecls, protoDollar[8].b)
 		}
-	case 107:
+	case 127:
 		protoDollar = protoS[protopt-5 : protopt+1]
-//line proto.y:582
+//line proto.y:653
 		{
 			protoVAL.mapFld = ast.NewMapFieldNode(protoDollar[1].mapType, protoDollar[2].id, protoDollar[3].b, protoDollar[4].i, nil, protoDollar[5].b)
 		}
-	case 108:
+	case 128:
 		protoDollar = protoS[protopt-6 : protopt+1]
-//line proto.y:585
+//line proto.y:656
 		{
 			protoVAL.mapFld = ast.NewMapFieldNode(protoDollar[1].mapType, protoDollar[2].id, protoDollar[3].b, protoDollar[4].i, protoDollar[5].cmpctOpts, protoDollar[6].b)
 		}
-	case 109:
+	case 129:
 		protoDollar = protoS[protopt-6 : protopt+1]
-//line proto.y:589
+//line proto.y:660
 		{
 			protoVAL.mapType = ast.NewMapTypeNode(protoDollar[1].id.ToKeyword(), protoDollar[2].b, protoDollar[3].id, protoDollar[4].b, protoDollar[5].tid, protoDollar[6].b)
 		}
-	case 122:
+	case 142:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:606
+//line proto.y:677
 		{
 			ranges, commas := protoDollar[2].rngs.toNodes()
 			protoVAL.ext = ast.NewExtensionRangeNode(protoDollar[1].id.ToKeyword(), ranges, commas, nil, protoDollar[3].b)
 		}
-	case 123:
+	case 143:
 		protoDollar = protoS[protopt-4 : protopt+1]
-//line proto.y:610
+//line proto.y:681
 		{
 			ranges, commas := protoDollar[2].rngs.toNodes()
 			protoVAL.ext = ast.NewExtensionRangeNode(protoDollar[1].id.ToKeyword(), ranges, commas, protoDollar[3].cmpctOpts, protoDollar[4].b)
 		}
-	case 124:
+	case 144:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:615
+//line proto.y:686
 		{
 			protoVAL.rngs = &rangeList{protoDollar[1].rng, nil, nil}
 		}
-	case 125:
+	case 145:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:618
+//line proto.y:689
 		{
 			protoVAL.rngs = &rangeList{protoDollar[1].rng, protoDollar[2].b, protoDollar[3].rngs}
 		}
-	case 126:
+	case 146:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:622
+//line proto.y:693
 		{
 			protoVAL.rng = ast.NewRangeNode(protoDollar[1].i, nil, nil, nil)
 		}
-	case 127:
+	case 147:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:625
+//line proto.y:696
 		{
 			protoVAL.rng = ast.NewRangeNode(protoDollar[1].i, protoDollar[2].id.ToKeyword(), protoDollar[3].i, nil)
 		}
-	case 128:
+	case 148:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:628
+//line proto.y:699
 		{
 			protoVAL.rng = ast.NewRangeNode(protoDollar[1].i, protoDollar[2].id.ToKeyword(), nil, protoDollar[3].id.ToKeyword())
 		}
-	case 129:
+	case 149:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:632
+//line proto.y:703
 		{
 			protoVAL.rngs = &rangeList{protoDollar[1].rng, nil, nil}
 		}
-	case 130:
+	case 150:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:635
+//line proto.y:706
 		{
 			protoVAL.rngs = &rangeList{protoDollar[1].rng, protoDollar[2].b, protoDollar[3].rngs}
 		}
-	case 131:
+	case 151:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:639
+//line proto.y:710
 		{
 			protoVAL.rng = ast.NewRangeNode(protoDollar[1].il, nil, nil, nil)
 		}
-	case 132:
+	case 152:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:642
+//line proto.y:713
 		{
 			protoVAL.rng = ast.NewRangeNode(protoDollar[1].il, protoDollar[2].id.ToKeyword(), protoDollar[3].il, nil)
 		}
-	case 133:
+	case 153:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:645
+//line proto.y:716
 		{
 			protoVAL.rng = ast.NewRangeNode(protoDollar[1].il, protoDollar[2].id.ToKeyword(), nil, protoDollar[3].id.ToKeyword())
 		}
-	case 134:
+	case 154:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:649
+//line proto.y:720
 		{
 			protoVAL.il = protoDollar[1].i
 		}
-	case 135:
+	case 155:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:652
+//line proto.y:723
 		{
 			protoVAL.il = ast.NewNegativeIntLiteralNode(protoDollar[1].b, protoDollar[2].i)
 		}
-	case 136:
+	case 156:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:656
+//line proto.y:727
 		{
 			ranges, commas := protoDollar[2].rngs.toNodes()
 			protoVAL.resvd = ast.NewReservedRangesNode(protoDollar[1].id.ToKeyword(), ranges, commas, protoDollar[3].b)
 		}
-	case 138:
+	case 158:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:662
+//line proto.y:733
 		{
 			ranges, commas := protoDollar[2].rngs.toNodes()
 			protoVAL.resvd = ast.NewReservedRangesNode(protoDollar[1].id.ToKeyword(), ranges, commas, protoDollar[3].b)
 		}
-	case 140:
+	case 160:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:668
+//line proto.y:739
 		{
 			names, commas := protoDollar[2].names.toNodes()
 			protoVAL.resvd = ast.NewReservedNamesNode(protoDollar[1].id.ToKeyword(), names, commas, protoDollar[3].b)
 		}
-	case 141:
+	case 161:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:673
+//line proto.y:744
 		{
 			protoVAL.names = &nameList{protoDollar[1].str.toStringValueNode(), nil, nil}
 		}
-	case 142:
+	case 162:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:676
+//line proto.y:747
 		{
 			protoVAL.names = &nameList{protoDollar[1].str.toStringValueNode(), protoDollar[2].b, protoDollar[3].names}
 		}
-	case 143:
+	case 163:
 		protoDollar = protoS[protopt-5 : protopt+1]
-//line proto.y:680
+//line proto.y:751
 		{
 			protoVAL.en = ast.NewEnumNode(protoDollar[1].id.ToKeyword(), protoDollar[2].id, protoDollar[3].b, protoDollar[4].enDecls, protoDollar[5].b)
 		}
-	case 144:
+	case 164:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:684
+//line proto.y:755
 		{
 			if protoDollar[2].enDecl != nil {
 				protoVAL.enDecls = append(protoDollar[1].enDecls, protoDollar[2].enDecl)
@@ -1947,9 +2174,9 @@ protodefault:
 				protoVAL.enDecls = protoDollar[1].enDecls
 			}
 		}
-	case 145:
+	case 165:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:691
+//line proto.y:762
 		{
 			if protoDollar[1].enDecl != nil {
 				protoVAL.enDecls = []ast.EnumElement{protoDollar[1].enDecl}
@@ -1957,69 +2184,69 @@ protodefault:
 				protoVAL.enDecls = nil
 			}
 		}
-	case 146:
+	case 166:
 		protoDollar = protoS[protopt-0 : protopt+1]
-//line proto.y:698
+//line proto.y:769
 		{
 			protoVAL.enDecls = nil
 		}
-	case 147:
+	case 167:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:702
+//line proto.y:773
 		{
 			protoVAL.enDecl = protoDollar[1].opt
 		}
-	case 148:
+	case 168:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:705
+//line proto.y:776
 		{
 			protoVAL.enDecl = protoDollar[1].env
 		}
-	case 149:
+	case 169:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:708
+//line proto.y:779
 		{
 			protoVAL.enDecl = protoDollar[1].resvd
 		}
-	case 150:
+	case 170:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:711
+//line proto.y:782
 		{
 			protoVAL.enDecl = ast.NewEmptyDeclNode(protoDollar[1].b)
 		}
-	case 151:
+	case 171:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:714
+//line proto.y:785
 		{
 			protoVAL.enDecl = nil
 		}
-	case 152:
+	case 172:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:717
+//line proto.y:788
 		{
 			protoVAL.enDecl = nil
 		}
-	case 153:
+	case 173:
 		protoDollar = protoS[protopt-4 : protopt+1]
-//line proto.y:721
+//line proto.y:792
 		{
 			protoVAL.env = ast.NewEnumValueNode(protoDollar[1].id, protoDollar[2].b, protoDollar[3].il, nil, protoDollar[4].b)
 		}
-	case 154:
+	case 174:
 		protoDollar = protoS[protopt-5 : protopt+1]
-//line proto.y:724
+//line proto.y:795
 		{
 			protoVAL.env = ast.NewEnumValueNode(protoDollar[1].id, protoDollar[2].b, protoDollar[3].il, protoDollar[4].cmpctOpts, protoDollar[5].b)
 		}
-	case 155:
+	case 175:
 		protoDollar = protoS[protopt-5 : protopt+1]
-//line proto.y:728
+//line proto.y:799
 		{
 			protoVAL.msg = ast.NewMessageNode(protoDollar[1].id.ToKeyword(), protoDollar[2].id, protoDollar[3].b, protoDollar[4].msgDecls, protoDollar[5].b)
 		}
-	case 156:
+	case 176:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:732
+//line proto.y:803
 		{
 			if protoDollar[2].msgDecl != nil {
 				protoVAL.msgDecls = append(protoDollar[1].msgDecls, protoDollar[2].msgDecl)
@@ -2027,9 +2254,9 @@ protodefault:
 				protoVAL.msgDecls = protoDollar[1].msgDecls
 			}
 		}
-	case 157:
+	case 177:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:739
+//line proto.y:810
 		{
 			if protoDollar[1].msgDecl != nil {
 				protoVAL.msgDecls = []ast.MessageElement{protoDollar[1].msgDecl}
@@ -2037,99 +2264,99 @@ protodefault:
 				protoVAL.msgDecls = nil
 			}
 		}
-	case 158:
+	case 178:
 		protoDollar = protoS[protopt-0 : protopt+1]
-//line proto.y:746
+//line proto.y:817
 		{
 			protoVAL.msgDecls = nil
 		}
-	case 159:
+	case 179:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:750
+//line proto.y:821
 		{
 			protoVAL.msgDecl = protoDollar[1].fld
 		}
-	case 160:
+	case 180:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:753
+//line proto.y:824
 		{
 			protoVAL.msgDecl = protoDollar[1].en
 		}
-	case 161:
+	case 181:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:756
+//line proto.y:827
 		{
 			protoVAL.msgDecl = protoDollar[1].msg
 		}
-	case 162:
+	case 182:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:759
+//line proto.y:830
 		{
 			protoVAL.msgDecl = protoDollar[1].extend
 		}
-	case 163:
+	case 183:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:762
+//line proto.y:833
 		{
 			protoVAL.msgDecl = protoDollar[1].ext
 		}
-	case 164:
+	case 184:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:765
+//line proto.y:836
 		{
 			protoVAL.msgDecl = protoDollar[1].grp
 		}
-	case 165:
+	case 185:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:768
+//line proto.y:839
 		{
 			protoVAL.msgDecl = protoDollar[1].opt
 		}
-	case 166:
+	case 186:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:771
+//line proto.y:842
 		{
 			protoVAL.msgDecl = protoDollar[1].oo
 		}
-	case 167:
+	case 187:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:774
+//line proto.y:845
 		{
 			protoVAL.msgDecl = protoDollar[1].mapFld
 		}
-	case 168:
+	case 188:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:777
+//line proto.y:848
 		{
 			protoVAL.msgDecl = protoDollar[1].resvd
 		}
-	case 169:
+	case 189:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:780
+//line proto.y:851
 		{
 			protoVAL.msgDecl = ast.NewEmptyDeclNode(protoDollar[1].b)
 		}
-	case 170:
+	case 190:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:783
+//line proto.y:854
 		{
 			protoVAL.msgDecl = nil
 		}
-	case 171:
+	case 191:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:786
+//line proto.y:857
 		{
 			protoVAL.msgDecl = nil
 		}
-	case 172:
+	case 192:
 		protoDollar = protoS[protopt-5 : protopt+1]
-//line proto.y:790
+//line proto.y:861
 		{
 			protoVAL.extend = ast.NewExtendNode(protoDollar[1].id.ToKeyword(), protoDollar[2].tid, protoDollar[3].b, protoDollar[4].extDecls, protoDollar[5].b)
 		}
-	case 173:
+	case 193:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:794
+//line proto.y:865
 		{
 			if protoDollar[2].extDecl != nil {
 				protoVAL.extDecls = append(protoDollar[1].extDecls, protoDollar[2].extDecl)
@@ -2137,9 +2364,9 @@ protodefault:
 				protoVAL.extDecls = protoDollar[1].extDecls
 			}
 		}
-	case 174:
+	case 194:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:801
+//line proto.y:872
 		{
 			if protoDollar[1].extDecl != nil {
 				protoVAL.extDecls = []ast.ExtendElement{protoDollar[1].extDecl}
@@ -2147,51 +2374,51 @@ protodefault:
 				protoVAL.extDecls = nil
 			}
 		}
-	case 175:
+	case 195:
 		protoDollar = protoS[protopt-0 : protopt+1]
-//line proto.y:808
+//line proto.y:879
 		{
 			protoVAL.extDecls = nil
 		}
-	case 176:
+	case 196:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:812
+//line proto.y:883
 		{
 			protoVAL.extDecl = protoDollar[1].fld
 		}
-	case 177:
+	case 197:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:815
+//line proto.y:886
 		{
 			protoVAL.extDecl = protoDollar[1].grp
 		}
-	case 178:
+	case 198:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:818
+//line proto.y:889
 		{
 			protoVAL.extDecl = ast.NewEmptyDeclNode(protoDollar[1].b)
 		}
-	case 179:
+	case 199:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:821
+//line proto.y:892
 		{
 			protoVAL.extDecl = nil
 		}
-	case 180:
+	case 200:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:824
+//line proto.y:895
 		{
 			protoVAL.extDecl = nil
 		}
-	case 181:
+	case 201:
 		protoDollar = protoS[protopt-5 : protopt+1]
-//line proto.y:828
+//line proto.y:899
 		{
 			protoVAL.svc = ast.NewServiceNode(protoDollar[1].id.ToKeyword(), protoDollar[2].id, protoDollar[3].b, protoDollar[4].svcDecls, protoDollar[5].b)
 		}
-	case 182:
+	case 202:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:832
+//line proto.y:903
 		{
 			if protoDollar[2].svcDecl != nil {
 				protoVAL.svcDecls = append(protoDollar[1].svcDecls, protoDollar[2].svcDecl)
@@ -2199,9 +2426,9 @@ protodefault:
 				protoVAL.svcDecls = protoDollar[1].svcDecls
 			}
 		}
-	case 183:
+	case 203:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:839
+//line proto.y:910
 		{
 			if protoDollar[1].svcDecl != nil {
 				protoVAL.svcDecls = []ast.ServiceElement{protoDollar[1].svcDecl}
@@ -2209,69 +2436,69 @@ protodefault:
 				protoVAL.svcDecls = nil
 			}
 		}
-	case 184:
+	case 204:
 		protoDollar = protoS[protopt-0 : protopt+1]
-//line proto.y:846
+//line proto.y:917
 		{
 			protoVAL.svcDecls = nil
 		}
-	case 185:
+	case 205:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:853
+//line proto.y:924
 		{
 			protoVAL.svcDecl = protoDollar[1].opt
 		}
-	case 186:
+	case 206:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:856
+//line proto.y:927
 		{
 			protoVAL.svcDecl = protoDollar[1].mtd
 		}
-	case 187:
+	case 207:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:859
+//line proto.y:930
 		{
 			protoVAL.svcDecl = ast.NewEmptyDeclNode(protoDollar[1].b)
 		}
-	case 188:
+	case 208:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:862
+//line proto.y:933
 		{
 			protoVAL.svcDecl = nil
 		}
-	case 189:
+	case 209:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:865
+//line proto.y:936
 		{
 			protoVAL.svcDecl = nil
 		}
-	case 190:
+	case 210:
 		protoDollar = protoS[protopt-6 : protopt+1]
-//line proto.y:869
+//line proto.y:940
 		{
 			protoVAL.mtd = ast.NewRPCNode(protoDollar[1].id.ToKeyword(), protoDollar[2].id, protoDollar[3].rpcType, protoDollar[4].id.ToKeyword(), protoDollar[5].rpcType, protoDollar[6].b)
 		}
-	case 191:
+	case 211:
 		protoDollar = protoS[protopt-8 : protopt+1]
-//line proto.y:872
+//line proto.y:943
 		{
 			protoVAL.mtd = ast.NewRPCNodeWithBody(protoDollar[1].id.ToKeyword(), protoDollar[2].id, protoDollar[3].rpcType, protoDollar[4].id.ToKeyword(), protoDollar[5].rpcType, protoDollar[6].b, protoDollar[7].rpcDecls, protoDollar[8].b)
 		}
-	case 192:
+	case 212:
 		protoDollar = protoS[protopt-4 : protopt+1]
-//line proto.y:876
+//line proto.y:947
 		{
 			protoVAL.rpcType = ast.NewRPCTypeNode(protoDollar[1].b, protoDollar[2].id.ToKeyword(), protoDollar[3].tid, protoDollar[4].b)
 		}
-	case 193:
+	case 213:
 		protoDollar = protoS[protopt-3 : protopt+1]
-//line proto.y:879
+//line proto.y:950
 		{
 			protoVAL.rpcType = ast.NewRPCTypeNode(protoDollar[1].b, nil, protoDollar[2].tid, protoDollar[3].b)
 		}
-	case 194:
+	case 214:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:883
+//line proto.y:954
 		{
 			if protoDollar[2].rpcDecl != nil {
 				protoVAL.rpcDecls = append(protoDollar[1].rpcDecls, protoDollar[2].rpcDecl)
@@ -2279,9 +2506,9 @@ protodefault:
 				protoVAL.rpcDecls = protoDollar[1].rpcDecls
 			}
 		}
-	case 195:
+	case 215:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:890
+//line proto.y:961
 		{
 			if protoDollar[1].rpcDecl != nil {
 				protoVAL.rpcDecls = []ast.RPCElement{protoDollar[1].rpcDecl}
@@ -2289,33 +2516,33 @@ protodefault:
 				protoVAL.rpcDecls = nil
 			}
 		}
-	case 196:
+	case 216:
 		protoDollar = protoS[protopt-0 : protopt+1]
-//line proto.y:897
+//line proto.y:968
 		{
 			protoVAL.rpcDecls = nil
 		}
-	case 197:
+	case 217:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:901
+//line proto.y:972
 		{
 			protoVAL.rpcDecl = protoDollar[1].opt
 		}
-	case 198:
+	case 218:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:904
+//line proto.y:975
 		{
 			protoVAL.rpcDecl = ast.NewEmptyDeclNode(protoDollar[1].b)
 		}
-	case 199:
+	case 219:
 		protoDollar = protoS[protopt-2 : protopt+1]
-//line proto.y:907
+//line proto.y:978
 		{
 			protoVAL.rpcDecl = nil
 		}
-	case 200:
+	case 220:
 		protoDollar = protoS[protopt-1 : protopt+1]
-//line proto.y:910
+//line proto.y:981
 		{
 			protoVAL.rpcDecl = nil
 		}


Test patch:
diff --git a/desc/protoparse/validate_test.go b/desc/protoparse/validate_test.go
index 8c8deac..bd5c06b 100644
--- a/desc/protoparse/validate_test.go
+++ b/desc/protoparse/validate_test.go
@@ -250,6 +250,70 @@ func TestBasicValidation(t *testing.T) {
 			contents: `message Foo { oneof foo { group bar = 1 { } } }`,
 			errMsg:   `test.proto:1:33: group bar should have a name that starts with a capital letter`,
 		},
+		{
+			contents: `enum Foo { option = 1; }`,
+			errMsg:   `test.proto:1:19: syntax error: unexpected '='`,
+		},
+		{
+			contents: `enum Foo { reserved = 1; }`,
+			errMsg:   `test.proto:1:21: syntax error: unexpected '=', expecting string literal or int literal or '-'`,
+		},
+		{
+			contents: `syntax = "proto3"; enum message { unset = 0; } message Foo { message bar = 1; }`,
+			errMsg:   `test.proto:1:74: syntax error: unexpected '=', expecting '{'`,
+		},
+		{
+			contents: `syntax = "proto3"; enum enum { unset = 0; } message Foo { enum bar = 1; }`,
+			errMsg:   `test.proto:1:68: syntax error: unexpected '=', expecting '{'`,
+		},
+		{
+			contents: `syntax = "proto3"; enum reserved { unset = 0; } message Foo { reserved bar = 1; }`,
+			errMsg:   `test.proto:1:72: syntax error: unexpected identifier, expecting string literal or int literal`,
+		},
+		{
+			contents: `syntax = "proto3"; enum extend { unset = 0; } message Foo { extend bar = 1; }`,
+			errMsg:   `test.proto:1:72: syntax error: unexpected '=', expecting '{'`,
+		},
+		{
+			contents: `syntax = "proto3"; enum oneof { unset = 0; } message Foo { oneof bar = 1; }`,
+			errMsg:   `test.proto:1:70: syntax error: unexpected '=', expecting '{'`,
+		},
+		{
+			contents: `syntax = "proto3"; enum optional { unset = 0; } message Foo { optional bar = 1; }`,
+			errMsg:   `test.proto:1:76: syntax error: unexpected '='`,
+		},
+		{
+			contents: `syntax = "proto3"; enum repeated { unset = 0; } message Foo { repeated bar = 1; }`,
+			errMsg:   `test.proto:1:76: syntax error: unexpected '='`,
+		},
+		{
+			contents: `syntax = "proto3"; enum required { unset = 0; } message Foo { required bar = 1; }`,
+			errMsg:   `test.proto:1:76: syntax error: unexpected '='`,
+		},
+		{
+			contents: `syntax = "proto3"; import "google/protobuf/descriptor.proto"; enum optional { unset = 0; } extend google.protobuf.MethodOptions { optional bar = 22222; }`,
+			errMsg:   `test.proto:1:144: syntax error: unexpected '='`,
+		},
+		{
+			contents: `syntax = "proto3"; import "google/protobuf/descriptor.proto"; enum repeated { unset = 0; } extend google.protobuf.MethodOptions { repeated bar = 22222; }`,
+			errMsg:   `test.proto:1:144: syntax error: unexpected '='`,
+		},
+		{
+			contents: `syntax = "proto3"; import "google/protobuf/descriptor.proto"; enum required { unset = 0; } extend google.protobuf.MethodOptions { required bar = 22222; }`,
+			errMsg:   `test.proto:1:144: syntax error: unexpected '='`,
+		},
+		{
+			contents: `syntax = "proto3"; enum optional { unset = 0; } message Foo { oneof bar { optional bar = 1; } }`,
+			errMsg:   `test.proto:1:75: syntax error: unexpected "optional"`,
+		},
+		{
+			contents: `syntax = "proto3"; enum repeated { unset = 0; } message Foo { oneof bar { repeated bar = 1; } }`,
+			errMsg:   `test.proto:1:75: syntax error: unexpected "repeated"`,
+		},
+		{
+			contents: `syntax = "proto3"; enum required { unset = 0; } message Foo { oneof bar { required bar = 1; } }`,
+			errMsg:   `test.proto:1:75: syntax error: unexpected "required"`,
+		},
 		{
 			contents: ``,
 			succeeds: true,