In progress: [Issue 94] Importing "google/protobuf/descriptor.proto"
does not work.
Got everything working with 'integration with protoc' disabled. What is
left is to tell protoc where to find descriptor.proto. Most likely in a
preference.
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java
index 59a0775..237a017 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java
@@ -23,6 +23,7 @@
import com.google.eclipse.protobuf.protobuf.Import;
import com.google.eclipse.protobuf.ui.util.Resources;
+import com.google.eclipse.protobuf.util.Imports;
import com.google.inject.Inject;
/**
@@ -38,6 +39,7 @@
private static final char QUOTE = '\"';
@Inject private EObjectAtOffsetHelper eObjectAtOffsetHelper;
+ @Inject private Imports imports;
@Inject private Resources resources;
@Override public IHyperlink[] detectHyperlinks(ITextViewer textViewer, final IRegion region,
@@ -57,13 +59,15 @@
public IHyperlink[] exec(XtextResource resource) {
EObject resolved = eObjectAtOffsetHelper.resolveElementAt(resource, region.getOffset());
if (!(resolved instanceof Import)) return NO_HYPERLINKS;
+ Import anImport = (Import) resolved;
+ if (imports.isImportingProtoDescriptor(anImport)) return NO_HYPERLINKS;
IRegion importUriRegion;
try {
importUriRegion = importUriRegion(document, region.getOffset());
} catch (BadLocationException e) {
return NO_HYPERLINKS;
}
- String importUri = ((Import) resolved).getImportURI();
+ String importUri = anImport.getImportURI();
IHyperlink hyperlink = new ImportHyperlink(createURI(importUri), importUriRegion, resources);
return new IHyperlink[] { hyperlink };
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/GenerateProtobuf.mwe2 b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/GenerateProtobuf.mwe2
index 492f4f0..cf43ef8 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/GenerateProtobuf.mwe2
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/GenerateProtobuf.mwe2
@@ -66,7 +66,7 @@
// java-based API for validation
fragment = validation.JavaValidatorFragment {
- composedCheck = "org.eclipse.xtext.validation.ImportUriValidator"
+ // composedCheck = "org.eclipse.xtext.validation.ImportUriValidator"
composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
// registerForImportedPackages = true
}
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 a4eb463..f1310a3 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
@@ -12,25 +12,26 @@
import static com.google.eclipse.protobuf.scoping.OptionType.*;
import static com.google.eclipse.protobuf.util.Closeables.close;
import static com.google.eclipse.protobuf.util.Encodings.UTF_8;
-import static java.util.Collections.unmodifiableCollection;
+import static java.util.Collections.*;
import static org.eclipse.xtext.EcoreUtil2.*;
import static org.eclipse.xtext.util.CancelIndicator.NullImpl;
import static org.eclipse.xtext.util.Strings.isEmpty;
-import com.google.eclipse.protobuf.protobuf.*;
-import com.google.eclipse.protobuf.protobuf.Enum;
-import com.google.eclipse.protobuf.util.*;
-import com.google.inject.Inject;
-
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.xtext.nodemodel.INode;
-import org.eclipse.xtext.parser.*;
-import org.eclipse.xtext.resource.XtextResource;
-
import java.io.*;
import java.net.URL;
import java.util.*;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.xtext.nodemodel.INode;
+import org.eclipse.xtext.parser.IParseResult;
+import org.eclipse.xtext.parser.IParser;
+import org.eclipse.xtext.resource.XtextResource;
+
+import com.google.eclipse.protobuf.protobuf.*;
+import com.google.eclipse.protobuf.protobuf.Enum;
+import com.google.eclipse.protobuf.util.ModelNodes;
+import com.google.inject.Inject;
+
/**
* Contains the elements from descriptor.proto (provided with protobuf's library.)
*
@@ -38,8 +39,11 @@
*/
public class ProtoDescriptor {
+ /** Path of proto.descriptor to use in imports. */
+ public static final String PATH = "google/protobuf/descriptor.proto";
+
private static final Map<String, OptionType> OPTION_DEFINITION_BY_NAME = new HashMap<String, OptionType>();
-
+
static {
OPTION_DEFINITION_BY_NAME.put("FileOptions", FILE);
OPTION_DEFINITION_BY_NAME.put("MessageOptions", MESSAGE);
@@ -47,7 +51,8 @@
OPTION_DEFINITION_BY_NAME.put("EnumOptions", ENUM);
OPTION_DEFINITION_BY_NAME.put("MethodOptions", METHOD);
}
-
+
+ private final List<Type> allTypes = new ArrayList<Type>();
private final Map<OptionType, Map<String, Property>> optionsByType = new HashMap<OptionType, Map<String, Property>>();
private final Map<String, Enum> enumsByName = new HashMap<String, Enum>();
@@ -92,7 +97,10 @@
}
private void initContents() {
- for (Message m : getAllContentsOfType(root, Message.class)) {
+ allTypes.addAll(getAllContentsOfType(root, Type.class));
+ for (Type t : allTypes) {
+ if (!(t instanceof Message)) continue;
+ Message m = (Message) t;
OptionType type = OPTION_DEFINITION_BY_NAME.get(m.getName());
if (type == null) continue;
initOptions(m, type);
@@ -141,7 +149,7 @@
public Property lookupOption(String name) {
return lookupOption(name, FILE, MESSAGE, ENUM, METHOD);
}
-
+
private Property lookupOption(String name, OptionType...types) {
for (OptionType type : types) {
Property p = lookupOption(name, type);
@@ -230,4 +238,12 @@
String typeName = node.getText();
return (isEmpty(typeName)) ? null : enumsByName.get(typeName.trim());
}
+
+ /**
+ * Returns all types in descriptor.proto.
+ * @return all types in descriptor.proto.
+ */
+ public List<Type> allTypes() {
+ return unmodifiableList(allTypes);
+ }
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportUriResolver.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportUriResolver.java
index 4fdd459..aed9f58 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportUriResolver.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportUriResolver.java
@@ -44,7 +44,6 @@
// anImport.setImportURI(originalUri);
return applied;
}
- if (from instanceof Import) resolveImportUri((Import) from);
return super.apply(from);
}
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 8ed5113..f8f4d35 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
@@ -17,11 +17,16 @@
import java.util.*;
-import org.eclipse.emf.common.util.*;
-import org.eclipse.emf.ecore.*;
-import org.eclipse.emf.ecore.resource.*;
-import org.eclipse.xtext.naming.*;
-import org.eclipse.xtext.resource.*;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.xtext.naming.IQualifiedNameProvider;
+import org.eclipse.xtext.naming.QualifiedName;
+import org.eclipse.xtext.resource.IEObjectDescription;
+import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.*;
@@ -50,6 +55,7 @@
@Inject private LocalNamesProvider localNamesProvider;
@Inject private ImportedNamesProvider importedNamesProvider;
@Inject private PackageResolver packageResolver;
+ @Inject private Imports imports;
@SuppressWarnings("unused")
IScope scope_TypeRef_type(TypeRef typeRef, EReference reference) {
@@ -104,15 +110,19 @@
}
private <T extends Type> Collection<IEObjectDescription> importedTypes(Protobuf root, Class<T> targetType) {
- List<Import> imports = finder.importsIn(root);
- if (imports.isEmpty()) return emptyList();
- return importedTypes(imports, finder.packageOf(root), targetType);
+ List<Import> allImports = finder.importsIn(root);
+ if (allImports.isEmpty()) return emptyList();
+ return importedTypes(allImports, finder.packageOf(root), targetType);
}
- private <T extends Type> Collection<IEObjectDescription> importedTypes(List<Import> imports, Package aPackage,
+ private <T extends Type> Collection<IEObjectDescription> importedTypes(List<Import> allImports, Package aPackage,
Class<T> targetType) {
List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
- for (Import anImport : imports) {
+ for (Import anImport : allImports) {
+ if (imports.isImportingProtoDescriptor(anImport)) {
+ descriptions.addAll(allBuiltInTypes(targetType));
+ continue;
+ }
Resource importedResource = importedResourceFrom(anImport);
Protobuf importedRoot = rootElementOf(importedResource);
descriptions.addAll(publicImportedTypes(importedRoot, targetType));
@@ -125,10 +135,24 @@
return descriptions;
}
+ private <T extends Type> Collection<IEObjectDescription> allBuiltInTypes(Class<T> targetType) {
+ List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
+ ProtoDescriptor descriptor = descriptorProvider.get();
+ for (Type t : descriptor.allTypes()) {
+ if (!targetType.isInstance(t)) continue;
+ T type = targetType.cast(t);
+ descriptions.addAll(fullyQualifiedNamesOf(type));
+ for (QualifiedName name : importedNamesProvider.namesOf(type)) {
+ descriptions.add(create(name, type));
+ }
+ }
+ return descriptions;
+ }
+
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);
+ List<Import> allImports = finder.publicImportsIn(root);
+ if (allImports.isEmpty()) return emptyList();
+ return importedTypes(allImports, finder.packageOf(root), targetType);
}
private Resource importedResourceFrom(Import anImport) {
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
new file mode 100644
index 0000000..c245f9d
--- /dev/null
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Imports.java
@@ -0,0 +1,33 @@
+/*
+ * 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
+ */
+package com.google.eclipse.protobuf.util;
+
+import com.google.eclipse.protobuf.protobuf.Import;
+import com.google.eclipse.protobuf.scoping.ProtoDescriptor;
+import com.google.inject.Singleton;
+
+/**
+ * Utility methods related to imports.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+@Singleton
+public class Imports {
+
+ /**
+ * Indicates whether the URL of the given import is equal to the path of descriptor.proto.
+ * @param anImport the import to check.
+ * @return {@code true} if the URL of the given import is equal to the path of descriptor.proto, {@code false}
+ * otherwise.
+ */
+ public boolean isImportingProtoDescriptor(Import anImport) {
+ if (anImport == null) return false;
+ return ProtoDescriptor.PATH.equals(anImport.getImportURI());
+ }
+}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator.java
index ce147b0..65833f7 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator.java
@@ -15,7 +15,8 @@
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
-import org.eclipse.xtext.naming.*;
+import org.eclipse.xtext.naming.IQualifiedNameProvider;
+import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.scoping.impl.ImportUriResolver;
import org.eclipse.xtext.validation.Check;
@@ -32,6 +33,7 @@
@Inject private FieldOptions fieldOptions;
@Inject private ImportUriResolver uriResolver;
@Inject private IQualifiedNameProvider qualifiedNameProvider;
+ @Inject private Imports imports;
@Inject private Properties properties;
@Check public void checkDefaultValueType(FieldOption option) {
@@ -58,6 +60,8 @@
}
private boolean isResolved(Import anImport) {
+ // global proto file, always available
+ if (imports.isImportingProtoDescriptor(anImport)) return true;
String importUri = anImport.getImportURI();
if (!isEmpty(importUri)) {
URI uri = URI.createURI(importUri);