Merge branch 'master' of https://code.google.com/p/protobuf-dt/ into
option-ref
Conflicts:
com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor.java
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
index 853b1c0..3e88b60 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
@@ -261,11 +261,6 @@
proposeAndAccept(name, context, acceptor);
}
- private ICompletionProposal createCompletionProposal(String proposal, String displayString,
- ContentAssistContext context) {
- return createCompletionProposal(proposal, displayString, defaultImage(), context);
- }
-
private void proposeAndAccept(String proposalText, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
acceptor.accept(createCompletionProposal(proposalText, context));
}
@@ -337,7 +332,8 @@
} else if (properties.isBool(option)) {
proposalText = proposalText + TRUE;
}
- ICompletionProposal proposal = createCompletionProposal(proposalText, displayString, context);
+ Image image = imageHelper.getImage(images.imageFor(Option.class));
+ ICompletionProposal proposal = createCompletionProposal(proposalText, displayString, image, context);
if (isStringOption && proposal instanceof ConfigurableCompletionProposal) {
// set cursor between the proposal's quotes
ConfigurableCompletionProposal configurable = (ConfigurableCompletionProposal) proposal;
@@ -417,4 +413,9 @@
String previousWord = styledText.getTextRange(start, valueLength);
return word.equals(previousWord);
}
+
+ /** {@inheritDoc} */
+ @Override public void completePropertyRef_Property(EObject model, Assignment assignment,
+ ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
+ }
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionDescriptions.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionDescriptions.java
index 716232e..d92fbfb 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionDescriptions.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionDescriptions.java
@@ -8,19 +8,23 @@
*/
package com.google.eclipse.protobuf.scoping;
-import static com.google.eclipse.protobuf.scoping.OptionType.*;
import static java.util.Collections.emptyList;
+import static org.eclipse.emf.common.util.URI.createURI;
+import static org.eclipse.emf.ecore.util.EcoreUtil.getAllContents;
import static org.eclipse.xtext.resource.EObjectDescription.create;
import java.util.*;
-import java.util.Map.Entry;
+import org.eclipse.emf.common.util.*;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.*;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
+import org.eclipse.xtext.scoping.impl.ImportUriResolver;
import com.google.eclipse.protobuf.protobuf.*;
-import com.google.eclipse.protobuf.protobuf.Enum;
+import com.google.eclipse.protobuf.protobuf.Package;
+import com.google.eclipse.protobuf.util.*;
import com.google.inject.Inject;
/**
@@ -28,19 +32,14 @@
*/
class OptionDescriptions {
- private static final Map<Class<?>, OptionType> OPTION_TYPES_BY_CONTAINER = new HashMap<Class<?>, OptionType>();
-
- static {
- OPTION_TYPES_BY_CONTAINER.put(Protobuf.class, FILE);
- OPTION_TYPES_BY_CONTAINER.put(Enum.class, ENUM);
- OPTION_TYPES_BY_CONTAINER.put(Message.class, MESSAGE);
- OPTION_TYPES_BY_CONTAINER.put(Service.class, SERVICE);
- OPTION_TYPES_BY_CONTAINER.put(Rpc.class, RPC);
- }
-
@Inject private ProtoDescriptorProvider descriptorProvider;
+ @Inject private ProtobufElementFinder finder;
+ @Inject private ImportedNamesProvider importedNamesProvider;
+ @Inject private Imports imports;
@Inject private LocalNamesProvider localNamesProvider;
+ @Inject private PackageResolver packageResolver;
@Inject private QualifiedNameDescriptions qualifiedNamesDescriptions;
+ @Inject private ImportUriResolver uriResolver;
Collection <IEObjectDescription> builtInOptionProperties(BuiltInOption option) {
ProtoDescriptor descriptor = descriptorProvider.get();
@@ -49,12 +48,11 @@
return emptyList();
}
- Collection <IEObjectDescription> localCustomOptionProperties(EObject root, CustomOption option) {
- return localCustomOptionProperties(root, option, 0);
+ Collection <IEObjectDescription> localCustomOptionProperties(EObject root, OptionType optionType) {
+ return localCustomOptionProperties(root, optionType, 0);
}
- private Collection <IEObjectDescription> localCustomOptionProperties(EObject root, CustomOption option, int level) {
- OptionType optionType = optionType(option);
+ private Collection <IEObjectDescription> localCustomOptionProperties(EObject root, OptionType optionType, int level) {
if (optionType == null) return emptyList();
List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
for (EObject element : root.eContents()) {
@@ -72,23 +70,87 @@
continue;
}
if (element instanceof Message) {
- descriptions.addAll(localCustomOptionProperties(element, option, level + 1));
+ descriptions.addAll(localCustomOptionProperties(element, optionType, level + 1));
}
}
return descriptions;
}
- private OptionType optionType(CustomOption option) {
- EObject container = option.eContainer();
- for (Entry<Class<?>, OptionType> optionTypeByContainer : OPTION_TYPES_BY_CONTAINER.entrySet()) {
- if (optionTypeByContainer.getKey().isInstance(container)) {
- return optionTypeByContainer.getValue();
- }
- }
- return null;
+ Collection<IEObjectDescription> importedCustomOptionProperties(Protobuf root, OptionType optionType) {
+ List<Import> allImports = finder.importsIn(root);
+ if (allImports.isEmpty()) return emptyList();
+ ResourceSet resourceSet = root.eResource().getResourceSet();
+ return importedCustomOptionProperties(allImports, finder.packageOf(root), resourceSet, optionType);
}
- private boolean isExtendingOptionMessage(EObject o, OptionType optionType) {
+ private Collection<IEObjectDescription> importedCustomOptionProperties(List<Import> allImports, Package aPackage,
+ ResourceSet resourceSet, OptionType optionType) {
+ List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
+ for (Import anImport : allImports) {
+ if (imports.isImportingDescriptor(anImport)) continue;
+ Resource importedResource = importedResource(anImport, resourceSet);
+ Protobuf importedRoot = finder.rootOf(importedResource);
+ if (importedRoot != null) {
+ descriptions.addAll(publicImportedCustomOptionProperties(importedRoot, optionType));
+ if (arePackagesRelated(aPackage, importedRoot)) {
+ descriptions.addAll(localCustomOptionProperties(importedRoot, optionType));
+ continue;
+ }
+ }
+ descriptions.addAll(localCustomOptionProperties(importedResource, optionType));
+ }
+ return descriptions;
+ }
+
+ private Resource importedResource(Import anImport, ResourceSet resourceSet) {
+ URI importUri = createURI(uriResolver.apply(anImport));
+ try {
+ return resourceSet.getResource(importUri, true);
+ } catch (Throwable t) {
+ return null;
+ }
+ }
+
+ private <T extends Type> Collection<IEObjectDescription> publicImportedCustomOptionProperties(Protobuf root,
+ OptionType optionType) {
+ List<Import> allImports = finder.publicImportsIn(root);
+ if (allImports.isEmpty()) return emptyList();
+ ResourceSet resourceSet = root.eResource().getResourceSet();
+ return importedCustomOptionProperties(allImports, finder.packageOf(root), resourceSet, optionType);
+ }
+
+ private boolean arePackagesRelated(Package aPackage, EObject root) {
+ Package p = finder.packageOf(root);
+ return packageResolver.areRelated(aPackage, p);
+ }
+
+ private Collection<IEObjectDescription> describe(Collection<Property> properties) {
+ List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
+ for (Property p : properties) {
+ descriptions.add(create(p.getName(), p));
+ }
+ return descriptions;
+ }
+
+ private Collection<IEObjectDescription> localCustomOptionProperties(Resource resource, OptionType optionType) {
+ List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
+ TreeIterator<Object> contents = getAllContents(resource, true);
+ while (contents.hasNext()) {
+ Object next = contents.next();
+ if (!isExtendingOptionMessage(next, optionType)) continue;
+ ExtendMessage extend = (ExtendMessage) next;
+ for (MessageElement e : extend.getElements()) {
+ if (!(e instanceof Property)) continue;
+ descriptions.addAll(qualifiedNamesDescriptions.qualifiedNames(e));
+ for (QualifiedName name : importedNamesProvider.namesOf(e)) {
+ descriptions.add(create(name, e));
+ }
+ }
+ }
+ return descriptions;
+ }
+
+ private boolean isExtendingOptionMessage(Object o, OptionType optionType) {
if (!(o instanceof ExtendMessage)) return false;
Message message = messageFrom((ExtendMessage) o);
if (message == null) return false;
@@ -99,12 +161,4 @@
MessageRef ref = extend.getMessage();
return ref == null ? null : ref.getType();
}
-
- private Collection<IEObjectDescription> describe(Collection<Property> properties) {
- List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
- for (Property p : properties) {
- descriptions.add(create(p.getName(), p));
- }
- return descriptions;
- }
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionType.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionType.java
index f5893a3..2c75f54 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionType.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionType.java
@@ -8,6 +8,14 @@
*/
package com.google.eclipse.protobuf.scoping;
+import java.util.*;
+import java.util.Map.Entry;
+
+import org.eclipse.emf.ecore.EObject;
+
+import com.google.eclipse.protobuf.protobuf.*;
+import com.google.eclipse.protobuf.protobuf.Enum;
+
/**
* @author alruiz@google.com (Alex Ruiz)
*/
@@ -15,9 +23,29 @@
FILE("FileOptions"), MESSAGE("MessageOptions"), FIELD("FieldOptions"), ENUM("EnumOptions"),
LITERAL("EnumValueOptions"), SERVICE("ServiceOptions"), RPC("MethodOptions");
+ private static final Map<Class<?>, OptionType> OPTION_TYPES_BY_CONTAINER = new HashMap<Class<?>, OptionType>();
+
+ static {
+ OPTION_TYPES_BY_CONTAINER.put(Protobuf.class, FILE);
+ OPTION_TYPES_BY_CONTAINER.put(Enum.class, ENUM);
+ OPTION_TYPES_BY_CONTAINER.put(Message.class, MESSAGE);
+ OPTION_TYPES_BY_CONTAINER.put(Service.class, SERVICE);
+ OPTION_TYPES_BY_CONTAINER.put(Rpc.class, RPC);
+ }
+
final String messageName;
private OptionType(String messageName) {
this.messageName = messageName;
}
-}
\ No newline at end of file
+
+ static OptionType optionType(CustomOption option) {
+ EObject container = option.eContainer();
+ for (Entry<Class<?>, OptionType> optionTypeByContainer : OPTION_TYPES_BY_CONTAINER.entrySet()) {
+ if (optionTypeByContainer.getKey().isInstance(container)) {
+ return optionTypeByContainer.getValue();
+ }
+ }
+ return null;
+ }
+}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor.java
index 70bdd4c..af6225f 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptor.java
@@ -46,11 +46,11 @@
private static final Map<String, OptionType> OPTION_DEFINITION_BY_NAME = new HashMap<String, OptionType>();
static {
- addOptionTypeMappings();
+ addOptionTypes(FILE, MESSAGE, FIELD, ENUM);
}
- private static void addOptionTypeMappings() {
- for (OptionType type : OptionType.values()) {
+ private static void addOptionTypes(OptionType...types) {
+ for (OptionType type : types) {
OPTION_DEFINITION_BY_NAME.put(type.messageName, type);
}
}
@@ -133,23 +133,33 @@
}
/**
- * Returns the options available for the given option container. The returned options are defined in
+ * Returns the options available for the given option or option container. The returned options are defined in
* {@code google/protobuf/descriptor.proto} (more details can be found
* <a href=http://code.google.com/apis/protocolbuffers/docs/proto.html#options" target="_blank">here</a>.)
- * @param optionContainer the given container of an option.
- * @return the options available for the given option container, or an empty collection if the are not any
- * options available for the given option container.
+ * @param o the given option or option container.
+ * @return the options available for the given option or option container, or an empty collection if the are not any
+ * options available.
*/
- public Collection<Property> availableOptionPropertiesFor(EObject optionContainer) {
- if (optionContainer instanceof Protobuf) return optionsOfType(FILE);
- if (optionContainer instanceof Enum) return optionsOfType(ENUM);
- if (optionContainer instanceof Message) return optionsOfType(MESSAGE);
- if (optionContainer instanceof Service) return optionsOfType(SERVICE);
- if (optionContainer instanceof Rpc) return optionsOfType(RPC);
+ public Collection<Property> availableOptionPropertiesFor(EObject o) {
+ EObject target = o;
+ if (target instanceof BuiltInOption) target = target.eContainer();
+ if (target instanceof Protobuf) return fileOptions();
+ if (target instanceof Enum) return enumOptions();
+ if (target instanceof Message) return messageOptions();
return emptyList();
}
/**
+ * Returns all the file-level options available. These are the options defined in
+ * {@code google/protobuf/descriptor.proto} (more details can be found
+ * <a href=http://code.google.com/apis/protocolbuffers/docs/proto.html#options" target="_blank">here</a>.)
+ * @return all the file-level options available.
+ */
+ public Collection<Property> fileOptions() {
+ return optionsOfType(FILE);
+ }
+
+ /**
* Looks up an option per name, as defined in {@code google/protobuf/descriptor.proto}
* (more details can be found <a
* href=http://code.google.com/apis/protocolbuffers/docs/proto.html#options" target="_blank">here</a>.)
@@ -184,6 +194,16 @@
}
/**
+ * Returns all the message-level options available. These are the options defined in
+ * {@code google/protobuf/descriptor.proto} (more details can be found
+ * <a href=http://code.google.com/apis/protocolbuffers/docs/proto.html#options" target="_blank">here</a>.)
+ * @return all the message-level options available.
+ */
+ public Collection<Property> messageOptions() {
+ return optionsOfType(MESSAGE);
+ }
+
+ /**
* Returns all the field-level options available. These are the options defined in
* {@code google/protobuf/descriptor.proto} (more details can be found
* <a href=http://code.google.com/apis/protocolbuffers/docs/proto.html#options" target="_blank">here</a>.)
@@ -192,7 +212,17 @@
public Collection<Property> fieldOptions() {
return optionsOfType(FIELD);
}
-
+
+ /**
+ * Returns all the enum-level options available. These are the options defined in
+ * {@code google/protobuf/descriptor.proto} (more details can be found
+ * <a href=http://code.google.com/apis/protocolbuffers/docs/proto.html#options" target="_blank">here</a>.)
+ * @return all the enum-level options available.
+ */
+ public Collection<Property> enumOptions() {
+ return optionsOfType(ENUM);
+ }
+
private Collection<Property> optionsOfType(OptionType type) {
return unmodifiableCollection(optionsByType.get(type).values());
}
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 be4bcc9..041fcc1 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
@@ -8,6 +8,8 @@
*/
package com.google.eclipse.protobuf.scoping;
+import static com.google.eclipse.protobuf.scoping.OptionType.optionType;
+
import java.util.*;
import org.eclipse.emf.ecore.*;
@@ -97,7 +99,13 @@
}
if (mayBeOption instanceof CustomOption) {
Protobuf root = finder.rootOf(propertyRef);
- descriptions.addAll(optionDescriptions.localCustomOptionProperties(root, (CustomOption) mayBeOption));
+ OptionType optionType = optionType((CustomOption) mayBeOption);
+ EObject current = mayBeOption.eContainer();
+ while (current != null) {
+ descriptions.addAll(optionDescriptions.localCustomOptionProperties(current, optionType));
+ current = current.eContainer();
+ }
+ descriptions.addAll(optionDescriptions.importedCustomOptionProperties(root, optionType));
}
return createScope(descriptions);
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/QualifiedNames.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/QualifiedNames.java
index eb5bdc0..a073fe8 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/QualifiedNames.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/QualifiedNames.java
@@ -33,7 +33,7 @@
return QualifiedName.create(segments.toArray(new String[segments.size()]));
}
- List<QualifiedName> addPackageNameSegments(QualifiedName name, Package p) {
+ Collection<QualifiedName> addPackageNameSegments(QualifiedName name, Package p) {
QualifiedName current = name;
List<String> segments = fqnSegments(p);
int segmentCount = segments.size();
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/TypeDescriptions.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/TypeDescriptions.java
index 5082138..8892b06 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/TypeDescriptions.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/TypeDescriptions.java
@@ -19,12 +19,12 @@
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.*;
import org.eclipse.xtext.naming.QualifiedName;
-import org.eclipse.xtext.resource.*;
+import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.scoping.impl.ImportUriResolver;
import com.google.eclipse.protobuf.protobuf.*;
import com.google.eclipse.protobuf.protobuf.Package;
-import com.google.eclipse.protobuf.util.ProtobufElementFinder;
+import com.google.eclipse.protobuf.util.*;
import com.google.inject.Inject;
/**
@@ -35,6 +35,7 @@
@Inject private ProtoDescriptorProvider descriptorProvider;
@Inject private ProtobufElementFinder finder;
@Inject private ImportedNamesProvider importedNamesProvider;
+ @Inject private Imports imports;
@Inject private LocalNamesProvider localNamesProvider;
@Inject private PackageResolver packageResolver;
@Inject private QualifiedNameDescriptions qualifiedNamesDescriptions;
@@ -65,19 +66,20 @@
<T extends Type> Collection<IEObjectDescription> importedTypes(Protobuf root, Class<T> targetType) {
List<Import> allImports = finder.importsIn(root);
if (allImports.isEmpty()) return emptyList();
- return importedTypes(allImports, finder.packageOf(root), targetType);
+ ResourceSet resourceSet = root.eResource().getResourceSet();
+ return importedTypes(allImports, finder.packageOf(root), resourceSet, targetType);
}
private <T extends Type> Collection<IEObjectDescription> importedTypes(List<Import> allImports, Package aPackage,
- Class<T> targetType) {
+ ResourceSet resourceSet, Class<T> targetType) {
List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
for (Import anImport : allImports) {
- if (isImportingDescriptor(anImport)) {
+ if (imports.isImportingDescriptor(anImport)) {
descriptions.addAll(allBuiltInTypes(targetType));
continue;
}
- Resource importedResource = importedResourceFrom(anImport);
- Protobuf importedRoot = rootElementOf(importedResource);
+ Resource importedResource = importedResource(anImport, resourceSet);
+ Protobuf importedRoot = finder.rootOf(importedResource);
if (importedRoot != null) {
descriptions.addAll(publicImportedTypes(importedRoot, targetType));
if (arePackagesRelated(aPackage, importedRoot)) {
@@ -85,16 +87,11 @@
continue;
}
}
- descriptions.addAll(children(importedResource, targetType));
+ descriptions.addAll(localTypes(importedResource, targetType));
}
return descriptions;
}
- private boolean isImportingDescriptor(Import anImport) {
- String descriptorLocation = descriptorProvider.descriptorLocation().toString();
- return descriptorLocation.equals(anImport.getImportURI());
- }
-
private <T extends Type> Collection<IEObjectDescription> allBuiltInTypes(Class<T> targetType) {
List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
ProtoDescriptor descriptor = descriptorProvider.get();
@@ -106,14 +103,7 @@
return descriptions;
}
- private <T extends Type> Collection<IEObjectDescription> publicImportedTypes(Protobuf root, Class<T> targetType) {
- List<Import> allImports = finder.publicImportsIn(root);
- if (allImports.isEmpty()) return emptyList();
- return importedTypes(allImports, finder.packageOf(root), targetType);
- }
-
- private Resource importedResourceFrom(Import anImport) {
- ResourceSet resourceSet = finder.rootOf(anImport).eResource().getResourceSet();
+ private Resource importedResource(Import anImport, ResourceSet resourceSet) {
URI importUri = createURI(uriResolver.apply(anImport));
try {
return resourceSet.getResource(importUri, true);
@@ -122,17 +112,11 @@
}
}
- 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 Protobuf) return (Protobuf) next;
- }
- return null;
+ private <T extends Type> Collection<IEObjectDescription> publicImportedTypes(Protobuf root, Class<T> targetType) {
+ List<Import> allImports = finder.publicImportsIn(root);
+ if (allImports.isEmpty()) return emptyList();
+ ResourceSet resourceSet = root.eResource().getResourceSet();
+ return importedTypes(allImports, finder.packageOf(root), resourceSet, targetType);
}
private boolean arePackagesRelated(Package aPackage, EObject root) {
@@ -140,7 +124,7 @@
return packageResolver.areRelated(aPackage, p);
}
- private <T extends Type> Collection<IEObjectDescription> children(Resource resource, Class<T> targetType) {
+ private <T extends Type> Collection<IEObjectDescription> localTypes(Resource resource, Class<T> targetType) {
List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
TreeIterator<Object> contents = getAllContents(resource, true);
while (contents.hasNext()) {
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Imports.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Imports.java
index ea34fd0..d2ed78e 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Imports.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Imports.java
@@ -11,7 +11,8 @@
import static com.google.eclipse.protobuf.scoping.ProtoDescriptor.DESCRIPTOR_IMPORT_URI;
import com.google.eclipse.protobuf.protobuf.Import;
-import com.google.inject.Singleton;
+import com.google.eclipse.protobuf.scoping.ProtoDescriptorProvider;
+import com.google.inject.*;
/**
* Utility methods related to imports.
@@ -21,6 +22,8 @@
@Singleton
public class Imports {
+ @Inject private ProtoDescriptorProvider descriptorProvider;
+
/**
* Indicates whether the URI of the given import is equal to the path of descriptor.proto
* ("google/protobuf/descriptor.proto").
@@ -42,4 +45,14 @@
public boolean isUnresolvedDescriptorUri(String uri) {
return DESCRIPTOR_IMPORT_URI.equals(uri);
}
+
+ /**
+ * Indicates whether the given <code>{@link Import}</code> is pointing to descriptor.proto.
+ * @param anImport the given import to check.
+ * @return {@code true} if the given import is pointing to descriptor.proto, {@code false} otherwise.
+ */
+ public boolean isImportingDescriptor(Import anImport) {
+ String descriptorLocation = descriptorProvider.descriptorLocation().toString();
+ return descriptorLocation.equals(anImport.getImportURI());
+ }
}
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 64ba56d..e3a255c 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
@@ -9,10 +9,14 @@
package com.google.eclipse.protobuf.util;
import static java.util.Collections.unmodifiableList;
+import static org.eclipse.emf.ecore.util.EcoreUtil.getAllContents;
import java.util.*;
+import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.xtext.resource.XtextResource;
import com.google.eclipse.protobuf.protobuf.*;
import com.google.eclipse.protobuf.protobuf.Enum;
@@ -103,4 +107,21 @@
}
return unmodifiableList(imports);
}
-}
+
+ /**
+ * Returns the root element of the given resource.
+ * @param resource the given resource.
+ * @return the root element of the given resource, or {@code null} if the given resource does not have a root element.
+ */
+ public Protobuf rootOf(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 Protobuf) return (Protobuf) next;
+ }
+ return null;
+ }}