Fixed: [Issue 87] Protobuf editor does not recognize "import public"
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/matchers/PropertyHasType.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/matchers/PropertyHasType.java
index 1a4464b..a5ce4d3 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/matchers/PropertyHasType.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/matchers/PropertyHasType.java
@@ -36,10 +36,10 @@
}
private String typeNameOf(Property property) {
- AbstractTypeReference r = property.getType();
- if (r instanceof ScalarTypeReference) return ((ScalarTypeReference) r).getScalar().getName();
- if (r instanceof TypeReference) {
- Type type = ((TypeReference) r).getType();
+ AbstractTypeRef r = property.getType();
+ if (r instanceof ScalarTypeRef) return ((ScalarTypeRef) r).getScalar().getName();
+ if (r instanceof TypeRef) {
+ Type type = ((TypeRef) r).getType();
return type == null ? null : type.getName();
}
return r.toString();
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/syntaxcoloring/ProtobufSemanticHighlightingCalculator.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/syntaxcoloring/ProtobufSemanticHighlightingCalculator.java
index e5208d4..f256ca4 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/syntaxcoloring/ProtobufSemanticHighlightingCalculator.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/syntaxcoloring/ProtobufSemanticHighlightingCalculator.java
@@ -151,9 +151,9 @@
}
private void highlightPropertyType(Property property, IHighlightedPositionAcceptor acceptor) {
- AbstractTypeReference ref = property.getType();
- if (!(ref instanceof TypeReference)) return;
- Type type = ((TypeReference) ref).getType();
+ AbstractTypeRef ref = property.getType();
+ if (!(ref instanceof TypeRef)) return;
+ Type type = ((TypeRef) ref).getType();
if (type instanceof Message) {
highlightFirstFeature(property, PROPERTY__TYPE, acceptor, MESSAGE_ID);
return;
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/Protobuf.xtext b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/Protobuf.xtext
index de2465b..e5f7485 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/Protobuf.xtext
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/Protobuf.xtext
@@ -8,26 +8,25 @@
*
* Author: alruiz@google.com (Alex Ruiz)
*/
-
grammar com.google.eclipse.protobuf.Protobuf with org.eclipse.xtext.common.Terminals
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate protobuf "http://www.google.com/eclipse/protobuf/Protobuf"
Protobuf:
- (syntax=Syntax)?
+ (syntax=Syntax)?
(elements+=ProtobufElement)*;
Syntax:
- 'syntax' '=' name=STRING ';';
+ 'syntax' '=' name=STRING ';';
ProtobufElement:
Package | Import | Option | Type | ExtendMessage | Service;
-
+
Package:
'package' name=QualifiedName ';';
-Import:
+Import:
RegularImport | PublicImport;
RegularImport:
@@ -41,11 +40,11 @@
Option:
BuiltInOption | CustomOption;
-
-BuiltInOption:
+
+BuiltInOption:
'option' name=Name '=' value=ValueRef ';';
-CustomOption:
+CustomOption:
'option' '(' name=QualifiedName ')' '=' value=ValueRef ';';
Type:
@@ -54,7 +53,7 @@
Message:
'message' name=Name '{'
elements+=MessageElement*
- '}'(';')?;
+ '}' (';')?;
MessageElement:
Extensions | Type | Field | ExtendMessage | Option;
@@ -72,26 +71,25 @@
Property | Group;
Group:
- modifier=Modifier 'group' name=Name '=' index=(INT | HEX)
+ modifier=Modifier 'group' name=Name '=' index=(INT | HEX)
('[' (fieldOptions+=FieldOption (',' fieldOptions+=FieldOption)*) ']')? '{'
elements+=GroupElement*
- '}'(';')?;
+ '}' (';')?;
GroupElement:
- Field | Option | Enum
-;
+ Field | Option | Enum;
Property:
- modifier=Modifier type=AbstractTypeReference name=Name '=' index=(INT | HEX)
+ modifier=Modifier type=AbstractTypeRef name=Name '=' index=(INT | HEX)
('[' fieldOptions+=FieldOption (',' fieldOptions+=FieldOption)* ']')? ';';
FieldOption:
BuiltInFieldOption | CustomFieldOption;
-
-BuiltInFieldOption:
+
+BuiltInFieldOption:
name=Name '=' value=ValueRef;
-CustomFieldOption:
+CustomFieldOption:
'(' name=QualifiedName ')' '=' value=ValueRef;
enum Modifier:
@@ -99,38 +97,21 @@
| optional
| repeated;
-AbstractTypeReference:
- ScalarTypeReference | TypeReference;
+AbstractTypeRef:
+ ScalarTypeRef | TypeRef;
-ScalarTypeReference:
+ScalarTypeRef:
scalar=ScalarType;
enum ScalarType:
- double
- | float
- | int32
- | int64
- | uint32
- | uint64
- | sint32
- | sint64
- | fixed32
- | fixed64
- | sfixed32
- | sfixed64
- | bool
- | string
- | bytes;
+ double | float | int32 | int64 | uint32 | uint64 | sint32 | sint64 | fixed32 | fixed64 | sfixed32 | sfixed64 | bool |
+ string | bytes;
-TypeReference:
- type=[Type | QualifiedName];
+TypeRef:
+ type=[Type|QualifiedName];
ValueRef:
- LiteralRef
- | BooleanRef
- | NumberRef
- | StringRef
- | Nan;
+ LiteralRef | BooleanRef | NumberRef | StringRef | Nan;
LiteralRef:
literal=[Literal];
@@ -151,12 +132,14 @@
IntRef:
int=INT;
-terminal INT returns ecore::EInt: SIGNED_INT;
-
+terminal INT returns ecore::EInt:
+ SIGNED_INT;
+
LongRef:
long=LONG;
-terminal LONG returns ecore::ELong: SIGNED_INT;
+terminal LONG returns ecore::ELong:
+ SIGNED_INT;
terminal SIGNED_INT:
('-')? (NUMBER)+;
@@ -164,25 +147,26 @@
FloatRef:
float=FLOAT;
-terminal FLOAT returns ecore::EFloat: DECIMAL;
+terminal FLOAT returns ecore::EFloat:
+ DECIMAL;
DoubleRef:
double=DOUBLE;
-terminal DOUBLE returns ecore::EDouble: DECIMAL;
+terminal DOUBLE returns ecore::EDouble:
+ DECIMAL;
terminal DECIMAL:
- ('-')? (NUMBER)* ('.' (NUMBER)+)?
-;
+ ('-')? (NUMBER)* ('.' (NUMBER)+)?;
StringRef:
string=STRING;
-terminal STRING:
+terminal STRING:
SL_STRING (SL_STRING)*;
terminal SL_STRING:
- '"' ( '\\' ('b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\') | !('\\'|'"') )* '"' (WS)*;
+ '"' ('\\' ('b' | 't' | 'n' | 'f' | 'r' | 'u' | '"' | "'" | '\\') | !('\\' | '"'))* '"' (WS)*;
Nan:
number='nan';
@@ -198,7 +182,8 @@
Literal:
name=Name '=' index=(INT | HEX) ';';
-terminal HEX returns ecore::EInt: '0x'(NUMBER|'a'..'f'|'A'..'F')+;
+terminal HEX returns ecore::EInt:
+ '0x' (NUMBER | 'a'..'f' | 'A'..'F')+;
terminal NUMBER:
'0'..'9';
@@ -206,17 +191,16 @@
ExtendMessage:
'extend' message=MessageRef '{'
elements+=MessageElement*
- '}'(';')?;
+ '}' (';')?;
Service:
- 'service' name=Name '{'
- rpcs+=Rpc*
- '}'(';')?;
+ 'service' name=Name '{'
+ rpcs+=Rpc*
+ '}' (';')?;
-Rpc:
- 'rpc' name=Name '(' argType=MessageRef ')' 'returns' '(' returnType=MessageRef ')'
- (('{' options+=Option* '}')(';')? | ';')
-;
+Rpc:
+ 'rpc' name=Name '(' argType=MessageRef ')' 'returns' '(' returnType=MessageRef ')'
+ (('{' options+=Option* '}') (';')? | ';');
Name:
ID | 'package' | 'import' | 'public' | 'option' | 'extend' | 'message' | 'optional' | 'required' | 'repeated' |
@@ -225,5 +209,5 @@
'sfixed32' | 'sfixed64' | 'bool' | 'string' | 'bytes';
MessageRef:
- type=[Message | QualifiedName];
+ type=[Message|QualifiedName];
\ No newline at end of file
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java
index d2f9d05..8ed5113 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java
@@ -52,7 +52,7 @@
@Inject private PackageResolver packageResolver;
@SuppressWarnings("unused")
- IScope scope_TypeReference_type(TypeReference typeRef, EReference reference) {
+ IScope scope_TypeRef_type(TypeRef typeRef, EReference reference) {
Protobuf root = finder.rootOf(typeRef);
Set<IEObjectDescription> descriptions = new HashSet<IEObjectDescription>();
EObject current = typeRef.eContainer().eContainer(); // get message of the property containing the TypeReference
@@ -69,7 +69,7 @@
}
@SuppressWarnings("unused")
- IScope scope_MessageReference_type(MessageRef msgRef, EReference reference) {
+ IScope scope_MessageRef_type(MessageRef msgRef, EReference reference) {
Protobuf root = finder.rootOf(msgRef);
Set<IEObjectDescription> descriptions = new HashSet<IEObjectDescription>();
descriptions.addAll(messagesIn(root));
@@ -106,21 +106,32 @@
private <T extends Type> Collection<IEObjectDescription> importedTypes(Protobuf root, Class<T> targetType) {
List<Import> imports = finder.importsIn(root);
if (imports.isEmpty()) return emptyList();
- Package importRootPackage = finder.packageOf(root);
+ return importedTypes(imports, finder.packageOf(root), targetType);
+ }
+
+ private <T extends Type> Collection<IEObjectDescription> importedTypes(List<Import> imports, Package aPackage,
+ Class<T> targetType) {
List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
for (Import anImport : imports) {
- Resource imported = importedResource(anImport);
- EObject importedRoot = rootElementOf(imported);
- if (importedRoot != null && arePackagesRelated(importRootPackage, importedRoot)) {
+ Resource importedResource = importedResourceFrom(anImport);
+ Protobuf importedRoot = rootElementOf(importedResource);
+ descriptions.addAll(publicImportedTypes(importedRoot, targetType));
+ if (importedRoot != null && arePackagesRelated(aPackage, importedRoot)) {
descriptions.addAll(typesIn(importedRoot));
continue;
}
- descriptions.addAll(children(imported, targetType));
+ descriptions.addAll(children(importedResource, targetType));
}
return descriptions;
}
- private Resource importedResource(Import anImport) {
+ private <T extends Type> Collection<IEObjectDescription> publicImportedTypes(Protobuf root, Class<T> targetType) {
+ List<Import> imports = finder.publicImportsIn(root);
+ if (imports.isEmpty()) return emptyList();
+ return importedTypes(imports, finder.packageOf(root), targetType);
+ }
+
+ private Resource importedResourceFrom(Import anImport) {
ResourceSet resourceSet = finder.rootOf(anImport).eResource().getResourceSet();
URI importUri = createURI(uriResolver.apply(anImport));
try {
@@ -130,12 +141,15 @@
}
}
- private /* Protobuf */ EObject rootElementOf(Resource resource) {
- if (resource instanceof XtextResource) return ((XtextResource) resource).getParseResult().getRootASTElement();
+ private Protobuf rootElementOf(Resource resource) {
+ if (resource instanceof XtextResource) {
+ EObject root = ((XtextResource) resource).getParseResult().getRootASTElement();
+ return (Protobuf) root;
+ }
TreeIterator<Object> contents = getAllContents(resource, true);
if (contents.hasNext()) {
Object next = contents.next();
- if (next instanceof EObject) return (EObject) next;
+ if (next instanceof Protobuf) return (Protobuf) next;
}
return null;
}
@@ -211,6 +225,4 @@
private static IScope createScope(Iterable<IEObjectDescription> descriptions) {
return new SimpleScope(descriptions, DO_NOT_IGNORE_CASE);
}
-
-
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Properties.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Properties.java
index 6762680..f556355 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Properties.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Properties.java
@@ -40,9 +40,9 @@
* @return {@code true} if the type of the given property is primitive, {@code false} otherwise.
*/
public boolean isPrimitive(Property p) {
- AbstractTypeReference r = p.getType();
- if (!(r instanceof ScalarTypeReference)) return false;
- String typeName = ((ScalarTypeReference) r).getScalar().getName();
+ AbstractTypeRef r = p.getType();
+ if (!(r instanceof ScalarTypeRef)) return false;
+ String typeName = ((ScalarTypeRef) r).getScalar().getName();
return !STRING.hasValue(typeName) && !BYTES.hasValue(typeName);
}
@@ -79,10 +79,10 @@
* @return the name of the type of the given {@code Property}.
*/
public String typeNameOf(Property p) {
- AbstractTypeReference r = p.getType();
- if (r instanceof ScalarTypeReference) return ((ScalarTypeReference) r).getScalar().getName();
- if (r instanceof TypeReference) {
- Type type = ((TypeReference) r).getType();
+ AbstractTypeRef r = p.getType();
+ if (r instanceof ScalarTypeRef) return ((ScalarTypeRef) r).getScalar().getName();
+ if (r instanceof TypeRef) {
+ Type type = ((TypeRef) r).getType();
return type == null ? null : type.getName();
}
return r.toString();
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/ProtobufElementFinder.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/ProtobufElementFinder.java
index 571f197..64ba56d 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/ProtobufElementFinder.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/ProtobufElementFinder.java
@@ -33,9 +33,9 @@
* @return the enum type of the given property or {@code null} if the type of the given property is not enum.
*/
public Enum enumTypeOf(Property p) {
- AbstractTypeReference aTypeRef = (p).getType();
- if (aTypeRef instanceof TypeReference) {
- Type type = ((TypeReference) aTypeRef).getType();
+ AbstractTypeRef aTypeRef = (p).getType();
+ if (aTypeRef instanceof TypeRef) {
+ Type type = ((TypeRef) aTypeRef).getType();
if (type instanceof Enum) return (Enum) type;
}
return null;
@@ -47,9 +47,9 @@
* @return the scalar type of the given property or {@code null} if the type of the given property is not a scalar.
*/
public ScalarType scalarTypeOf(Property p) {
- AbstractTypeReference aTypeRef = (p).getType();
- if (aTypeRef instanceof ScalarTypeReference)
- return ((ScalarTypeReference) aTypeRef).getScalar();
+ AbstractTypeRef aTypeRef = (p).getType();
+ if (aTypeRef instanceof ScalarTypeRef)
+ return ((ScalarTypeRef) aTypeRef).getScalar();
return null;
}
@@ -90,4 +90,17 @@
}
return unmodifiableList(imports);
}
+
+ /**
+ * Returns all the public import definitions in the given proto.
+ * @param root the given proto.
+ * @return all the public import definitions in the given proto.
+ */
+ public List<Import> publicImportsIn(Protobuf root) {
+ List<Import> imports = new ArrayList<Import>();
+ for (ProtobufElement e : root.getElements()) {
+ if (e instanceof PublicImport) imports.add((Import) e);
+ }
+ return unmodifiableList(imports);
+ }
}