|  | /* | 
|  | * Copyright (c) 2011 Google Inc. | 
|  | * | 
|  | * All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse | 
|  | * Public License v1.0 which accompanies this distribution, and is available at | 
|  | * | 
|  | * http://www.eclipse.org/legal/epl-v10.html | 
|  | * | 
|  | * Author: alruiz@google.com (Alex Ruiz) | 
|  | */ | 
|  | grammar com.google.eclipse.protobuf.Protobuf hidden(WS, ML_COMMENT, SL_COMMENT) | 
|  |  | 
|  | import "http://www.eclipse.org/emf/2002/Ecore" as ecore | 
|  | generate protobuf "http://www.google.com/eclipse/protobuf/Protobuf" | 
|  |  | 
|  | Protobuf: | 
|  | (syntax=Syntax)? | 
|  | (elements+=ProtobufElement)*; | 
|  |  | 
|  | Syntax: | 
|  | 'syntax' '=' name=STRING ';'; | 
|  |  | 
|  | ProtobufElement: | 
|  | Package | Import | Option | ComplexType | TypeExtension | Service; | 
|  |  | 
|  | Package: | 
|  | 'package' name=PackageName ';'; | 
|  |  | 
|  | PackageName: | 
|  | IdOrReservedWord ('.' IdOrReservedWord)*; | 
|  |  | 
|  | Import: | 
|  | NormalImport | PublicImport; | 
|  |  | 
|  | NormalImport: | 
|  | 'import' importURI=STRING ';'; | 
|  |  | 
|  | PublicImport: | 
|  | 'import' 'public' importURI=STRING ';'; | 
|  |  | 
|  | ComplexType: | 
|  | Enum | ExtensibleType; | 
|  |  | 
|  | Message: | 
|  | 'message' name=Name '{' | 
|  | elements+=MessageElement* | 
|  | '}' (';')?; | 
|  |  | 
|  | MessageElement: | 
|  | Option | Extensions | ComplexType | MessageField | TypeExtension; | 
|  |  | 
|  | Range: | 
|  | from=LONG ('to' to=RangeMax)?; | 
|  |  | 
|  | RangeMax: | 
|  | LONG | 'max'; | 
|  |  | 
|  | Group: | 
|  | modifier=Modifier 'group' name=Name '=' index=(LONG | HEX) | 
|  | ('[' (fieldOptions+=FieldOption (',' fieldOptions+=FieldOption)*) ']')? '{' | 
|  | elements+=GroupElement* | 
|  | '}' (';')?; | 
|  |  | 
|  | GroupElement: | 
|  | Option | IndexedElement | ComplexType | TypeExtension | Extensions; | 
|  |  | 
|  | Extensions: | 
|  | 'extensions' ranges+=Range (',' ranges+=Range)* ';'; | 
|  |  | 
|  | MessageField: | 
|  | =>modifier=Modifier type=TypeLink name=Name '=' index=(LONG | HEX) | 
|  | ('[' (fieldOptions+=FieldOption (',' fieldOptions+=FieldOption)*)? ']')? (';')+; | 
|  |  | 
|  | enum Modifier: | 
|  | required | optional | repeated; | 
|  |  | 
|  | TypeLink: | 
|  | ScalarTypeLink | ComplexTypeLink; | 
|  |  | 
|  | ScalarTypeLink: | 
|  | target=ScalarType; | 
|  |  | 
|  | enum ScalarType: | 
|  | double | float | int32 | int64 | uint32 | uint64 | sint32 | sint64 | fixed32 | fixed64 | sfixed32 | sfixed64 | bool | | 
|  | string | bytes; | 
|  |  | 
|  | ComplexTypeLink: | 
|  | target=[ComplexType|QualifiedName]; | 
|  |  | 
|  | Enum: | 
|  | =>'enum' name=Name '{' | 
|  | elements+=EnumElement* | 
|  | '}' ';'?; | 
|  |  | 
|  | EnumElement: | 
|  | Option | Literal; | 
|  |  | 
|  | Literal: | 
|  | name=Name '=' index=(LONG | HEX) | 
|  | ('[' fieldOptions+=FieldOption (',' fieldOptions+=FieldOption)* ']')? ';'; | 
|  |  | 
|  | terminal HEX returns ecore::ELong: | 
|  | ('-')? '0x' (NUMBER | 'a'..'f' | 'A'..'F')+; | 
|  |  | 
|  | TypeExtension: | 
|  | =>'extend' type=ExtensibleTypeLink '{' | 
|  | elements+=MessageElement* | 
|  | '}' (';')?; | 
|  |  | 
|  | ExtensibleTypeLink: | 
|  | target=[ExtensibleType|QualifiedName]; | 
|  |  | 
|  | ExtensibleType: | 
|  | Message | Group; | 
|  |  | 
|  | Service: | 
|  | 'service' name=Name '{' | 
|  | (elements+=ServiceElement)* | 
|  | '}' (';')?; | 
|  |  | 
|  | ServiceElement: | 
|  | Option | Rpc; | 
|  |  | 
|  | Rpc: | 
|  | 'rpc' name=Name '(' argType=MessageLink ')' 'returns' '(' returnType=MessageLink ')' | 
|  | (('{' options+=Option* '}') (';')? | ';'); | 
|  |  | 
|  | Name: | 
|  | IdOrReservedWord; | 
|  |  | 
|  | IdOrReservedWord: | 
|  | ID | ReservedWord; | 
|  |  | 
|  | MessageLink: | 
|  | target=[Message|QualifiedName]; | 
|  |  | 
|  | Option: | 
|  | NativeOption | CustomOption; | 
|  |  | 
|  | NativeOption: | 
|  | 'option' source=OptionSource '=' value=Value ';'; | 
|  |  | 
|  | CustomOption: | 
|  | 'option' '(' source=OptionSource ')' | 
|  | ('.' fields+=OptionField ('.' fields+=OptionField)*)? '=' value=Value ';'; | 
|  |  | 
|  | FieldOption: | 
|  | DefaultValueFieldOption | NativeFieldOption | CustomFieldOption; | 
|  |  | 
|  | DefaultValueFieldOption: | 
|  | =>'default' '=' value=Value; | 
|  |  | 
|  | NativeFieldOption: | 
|  | source=OptionSource '=' value=Value; | 
|  |  | 
|  | CustomFieldOption: | 
|  | '(' source=OptionSource ')' | 
|  | ('.' fields+=OptionField ('.' fields+=OptionField)*)? '=' value=Value; | 
|  |  | 
|  | OptionSource: | 
|  | target=[IndexedElement|QualifiedName]; | 
|  |  | 
|  | OptionField: | 
|  | MessageOptionField | '(' ExtensionOptionField ')'; | 
|  |  | 
|  | MessageOptionField: | 
|  | target=[IndexedElement]; | 
|  |  | 
|  | ExtensionOptionField: | 
|  | target=[IndexedElement|QualifiedName]; | 
|  |  | 
|  | IndexedElement: | 
|  | =>MessageField | Group; | 
|  |  | 
|  | Value: | 
|  | ComplexValue | SimpleValueLink; | 
|  |  | 
|  | // { foo: 1, bar: 2 } | 
|  | ComplexValue: | 
|  | '{' | 
|  | fields+=ValueField ((',')? fields+=ValueField)* | 
|  | '}'; | 
|  |  | 
|  | ValueField: | 
|  | SimpleValueField | ComplexValueField; | 
|  |  | 
|  | SimpleValueField: | 
|  | name=FieldName ':' value=SimpleValueLink; | 
|  |  | 
|  | ComplexValueField: | 
|  | name=FieldName ':'? values=ComplexValue; | 
|  |  | 
|  | FieldName: | 
|  | NormalFieldName | ExtensionFieldName; | 
|  |  | 
|  | NormalFieldName: | 
|  | target=[MessageField]; | 
|  |  | 
|  | ExtensionFieldName: | 
|  | '[' target=[MessageField|QualifiedName] ']'; | 
|  |  | 
|  | QualifiedName: | 
|  | '.'? SafeId ('.' SafeId)*; | 
|  |  | 
|  | SafeId: | 
|  | ID | SafeReservedWord; | 
|  |  | 
|  | ReservedWord: | 
|  | SafeReservedWord | 'group'; | 
|  |  | 
|  | SafeReservedWord: | 
|  | 'package' | 'import' | 'public' | 'option' | 'extend' | 'message' | 'optional' | 'required' | 'repeated' | | 
|  | 'enum' | 'service' | 'rpc' | 'returns' | 'default' | 'extensions' | 'to' | 'max' | 'true' | 'false' | | 
|  | 'double' | 'float' | 'int32' | 'int64' | 'uint32' | 'uint64' | 'sint32' | 'sint64' | 'fixed32' | 'fixed64' | | 
|  | 'sfixed32' | 'sfixed64' | 'bool' | 'string' | 'bytes'; | 
|  |  | 
|  | SimpleValueLink: | 
|  | LiteralLink | BooleanLink | NumberLink | StringLink; | 
|  |  | 
|  | LiteralLink: | 
|  | target=[Literal]; | 
|  |  | 
|  | BooleanLink: | 
|  | target=BOOL; | 
|  |  | 
|  | enum BOOL: | 
|  | true | false; | 
|  |  | 
|  | NumberLink: | 
|  | HexNumberLink | LongLink | DoubleLink; | 
|  |  | 
|  | HexNumberLink: | 
|  | target=HEX; | 
|  |  | 
|  | LongLink: | 
|  | target=LONG; | 
|  |  | 
|  | terminal LONG returns ecore::ELong: | 
|  | ('-')? (NUMBER)+; | 
|  |  | 
|  | DoubleLink: | 
|  | target=DOUBLE; | 
|  |  | 
|  | terminal DOUBLE returns ecore::EDouble: | 
|  | ('-')? (NUMBER)* ('.' (NUMBER)+)? | | 
|  | ('-')? (NUMBER)+ ('.') | | 
|  | ('-')? (NUMBER)+ (('e'|'E')('-')? (NUMBER)+) | | 
|  | 'nan' | 'inf' | '-inf'; | 
|  |  | 
|  | terminal NUMBER: | 
|  | '0'..'9'; | 
|  |  | 
|  | StringLink: | 
|  | target=STRING; | 
|  |  | 
|  | terminal STRING: | 
|  | SL_STRING (SL_STRING)*; | 
|  |  | 
|  | terminal SL_STRING: | 
|  | '"' ('\\' ('"' | "'" | '\\' | !('\\' | '"')) | !('\\' | '"'))* '"' (WS)* | | 
|  | "'" ('\\' ('"' | "'" | '\\' | !('\\' | "'")) | !('\\' | "'"))* "'" (WS)*; | 
|  |  | 
|  | terminal ID: '^'?('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*; | 
|  | terminal ML_COMMENT: '/*' -> '*/'; | 
|  | terminal SL_COMMENT: '//' !('\n'|'\r')* ('\r'? '\n')?; | 
|  | terminal WS: (' '|'\t'|'\r'|'\n')+; | 
|  | terminal ANY_OTHER: .; |