In progress: [Issue 95] Add ability to view descriptor.proto in an
editor
Path of descriptor of descriptor.proto gets properly resolved to the
file provided in the plug-in. Added code to create the correct
IEditorInfo when a URI belongs a platform plug-in resource.
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ProtobufUriEditorOpener.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ProtobufUriEditorOpener.java
index 892de15..acdcd3a 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ProtobufUriEditorOpener.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ProtobufUriEditorOpener.java
@@ -8,7 +8,6 @@
*/
package com.google.eclipse.protobuf.ui.editor;
-import static com.google.eclipse.protobuf.ui.util.Resources.URI_SCHEME_FOR_FILES;
import static org.eclipse.xtext.ui.editor.utils.EditorUtils.getXtextEditor;
import org.apache.log4j.Logger;
@@ -29,19 +28,26 @@
private static Logger logger = Logger.getLogger(ProtobufUriEditorOpener.class);
@Inject private Resources resources;
-
+
/** {@inheritDoc} */
@Override public IEditorPart open(URI uri, EReference crossReference, int indexInList, boolean select) {
- if (URI_SCHEME_FOR_FILES.equals(uri.scheme())) {
- try {
- IEditorPart editor = resources.openProtoFileInFileSystem(uri.trimFragment());
+ try {
+ IEditorPart editor = editorFor(uri);
+ if (editor != null) {
selectAndReveal(editor, uri, crossReference, indexInList, select);
return getXtextEditor(editor);
- } catch (PartInitException e) {
- logger.error("Unable to open " + uri.toString(), e);
}
+ } catch (PartInitException e) {
+ logger.error("Unable to open " + uri.toString(), e);
}
return super.open(uri, crossReference, indexInList, select);
}
+ private IEditorPart editorFor(URI uri) throws PartInitException {
+ if (uri.isFile())
+ return resources.openProtoFileInFileSystem(uri.trimFragment());
+ if (uri.isPlatformPlugin())
+ return resources.openProtoFileInPlugin(uri);
+ return null;
+ }
}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ImportHyperlink.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ImportHyperlink.java
index 26c901a..9aef26d 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ImportHyperlink.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ImportHyperlink.java
@@ -8,8 +8,6 @@
*/
package com.google.eclipse.protobuf.ui.editor.hyperlinking;
-import static com.google.eclipse.protobuf.ui.util.Resources.URI_SCHEME_FOR_FILES;
-
import org.apache.log4j.Logger;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jface.text.IRegion;
@@ -26,7 +24,7 @@
class ImportHyperlink implements IHyperlink {
private static Logger logger = Logger.getLogger(ImportHyperlink.class);
-
+
private final URI importUri;
private final IRegion region;
private final Resources resources;
@@ -38,10 +36,16 @@
}
public void open() {
- String scheme = importUri.scheme();
try {
- if ("platform".equals(scheme)) resources.openProtoFileInPlatform(importUri);
- if (URI_SCHEME_FOR_FILES.equals(scheme)) resources.openProtoFileInFileSystem(importUri);
+ if (importUri.isPlatformResource()) {
+ resources.openProtoFileInWorkspace(importUri);
+ return;
+ }
+ if (importUri.isPlatformPlugin()) {
+ resources.openProtoFileInPlugin(importUri);
+ return;
+ }
+ if (importUri.isFile()) resources.openProtoFileInFileSystem(importUri);
} catch (PartInitException e) {
logger.error("Unable to open " + importUri.toString(), e);
}
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 9bfe90a..b7abcae 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
@@ -60,11 +60,6 @@
EObject resolved = eObjectAtOffsetHelper.resolveElementAt(resource, region.getOffset());
if (!(resolved instanceof Import)) return NO_HYPERLINKS;
Import anImport = (Import) resolved;
- if (imports.isImportingProtoDescriptor(anImport)) {
- // TODO add support for opening descriptor.proto from plug-in
- // Look into NonExistingFileEditorInput
- return NO_HYPERLINKS;
- }
IRegion importUriRegion;
try {
importUriRegion = importUriRegion(document, region.getOffset());
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileUriResolver.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileUriResolver.java
index c509ea5..8353581 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileUriResolver.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/scoping/FileUriResolver.java
@@ -15,8 +15,11 @@
import org.eclipse.emf.ecore.resource.Resource;
import com.google.eclipse.protobuf.scoping.IFileUriResolver;
-import com.google.eclipse.protobuf.ui.preferences.pages.paths.*;
+import com.google.eclipse.protobuf.scoping.ProtoDescriptorProvider;
+import com.google.eclipse.protobuf.ui.preferences.pages.paths.PathsPreferences;
+import com.google.eclipse.protobuf.ui.preferences.pages.paths.PathsPreferencesFactory;
import com.google.eclipse.protobuf.ui.util.Resources;
+import com.google.eclipse.protobuf.util.Imports;
import com.google.inject.Inject;
/**
@@ -28,6 +31,8 @@
@Inject private PathsPreferencesFactory preferencesFactory;
@Inject private FileResolverStrategies resolvers;
+ @Inject private Imports imports;
+ @Inject private ProtoDescriptorProvider descriptorProvider;
@Inject private Resources resources;
/*
@@ -57,6 +62,9 @@
}
private String resolveUri(String importUri, URI resourceUri) {
+ if (imports.isUnresolvedDescriptorUri(importUri)) {
+ return descriptorProvider.descriptorLocation().toString();
+ }
IProject project = resources.project(resourceUri);
if (project == null) project = resources.activeProject();
if (project == null) throw new IllegalStateException("Unable to find current project");
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Resources.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Resources.java
index 7cb6c9a..1e9b653 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Resources.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Resources.java
@@ -8,13 +8,17 @@
*/
package com.google.eclipse.protobuf.ui.util;
-import org.eclipse.core.filesystem.*;
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.*;
-import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.*;
import org.eclipse.ui.ide.FileStoreEditorInput;
+import org.eclipse.ui.internal.editors.text.EditorsPlugin;
+import org.eclipse.ui.internal.editors.text.NonExistingFileEditorInput;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.views.navigator.ResourceNavigator;
@@ -65,19 +69,19 @@
}
/**
- * Opens the .proto file identified by the given URI. The .proto file exists in the workspace.
+ * Opens the .proto file identified by the given URI that exists in the workspace.
* @param uri the URI of the file to open.
* @return an open and active editor, or {@code null} if an external editor was opened.
* @throws PartInitException if the editor cannot be opened or initialized.
*/
- public IEditorPart openProtoFileInPlatform(URI uri) throws PartInitException {
+ public IEditorPart openProtoFileInWorkspace(URI uri) throws PartInitException {
IFile file = file(uri);
IEditorInput editorInput = new FileEditorInput(file);
return openFile(editorInput);
}
/**
- * Opens the .proto file identified by the given URI. The .proto file does not exist in the workspace, therefore is
+ * Opens the .proto file identified by the given URI that does not exist in the workspace, therefore is
* opened from the file system.
* @param uri the URI of the file to open.
* @return an open and active editor, or {@code null} if an external editor was opened.
@@ -89,6 +93,20 @@
return openFile(editorInput/*"org.eclipse.ui.DefaultTextEditor"*/);
}
+ @SuppressWarnings("restriction")
+ public IEditorPart openProtoFileInPlugin(URI uri) throws PartInitException {
+ IFileStore fileStore = queryFileStore();
+ IEditorInput editorInput = new NonExistingFileEditorInput(fileStore, "descriptor.proto");
+ return openFile(editorInput);
+ }
+
+ @SuppressWarnings("restriction")
+ private IFileStore queryFileStore() {
+ IPath stateLocation = EditorsPlugin.getDefault().getStateLocation();
+ IPath path = stateLocation.append("/_" + new Object().hashCode()); //$NON-NLS-1$
+ return EFS.getLocalFileSystem().getStore(path);
+ }
+
private IEditorPart openFile(IEditorInput editorInput) throws PartInitException {
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
return page.openEditor(editorInput, "com.google.eclipse.protobuf.Protobuf");
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 f1310a3..e10394d 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
@@ -39,9 +39,6 @@
*/
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 {
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptorProvider.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptorProvider.java
index 8cc6b2b..94c7523 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptorProvider.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtoDescriptorProvider.java
@@ -10,13 +10,14 @@
import static org.eclipse.xtext.util.Strings.isEmpty;
-import com.google.eclipse.protobuf.util.ModelNodes;
-import com.google.inject.*;
-
-import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.emf.common.util.URI;
import org.eclipse.xtext.parser.IParser;
+import com.google.eclipse.protobuf.util.ModelNodes;
+import com.google.inject.*;
+
/**
* Provider of a singleton instance of <code>{@link ProtoDescriptor}</code>.
*
@@ -32,6 +33,7 @@
@Inject private IExtensionRegistry registry;
private ProtoDescriptor descriptor;
+ private URI descriptorLocation;
private final Object lock = new Object();
@@ -40,17 +42,27 @@
if (descriptor == null) {
descriptor = new ProtoDescriptor(parser, descriptorLocation(), nodes);
}
- return descriptor;
}
+ return descriptor;
}
-
- private URI descriptorLocation() {
+
+ public URI descriptorLocation() {
+ synchronized (lock) {
+ if (descriptorLocation == null) descriptorLocation = findDescriptorLocation();
+ }
+ return descriptorLocation;
+ }
+
+ private URI findDescriptorLocation() {
+ String uri = null;
IConfigurationElement[] config = registry.getConfigurationElementsFor(EXTENSION_ID);
for (IConfigurationElement e : config) {
String path = e.getAttribute("path");
if (isEmpty(path)) continue;
- return URI.createURI("platform:/plugin/" + e.getContributor().getName() + "/" + path);
+ uri = "platform:/plugin/" + e.getContributor().getName() + "/" + path;
+ break;
}
- return URI.createURI("platform:/plugin/com.google.eclipse.protobuf/descriptor.proto");
+ if (uri == null) uri = "platform:/plugin/com.google.eclipse.protobuf/descriptor.proto";
+ return URI.createURI(uri);
}
}
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 aed9f58..2f9aae5 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
@@ -38,11 +38,8 @@
@Override public String apply(EObject from) {
if (from instanceof Import) {
Import anImport = (Import) from;
- // String originalUri = anImport.getImportURI();
anImport.setImportURI(resolveImportUri(anImport));
- String applied = super.apply(from);
- // anImport.setImportURI(originalUri);
- return applied;
+ return super.apply(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 f8f4d35..cb3d5b1 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
@@ -119,7 +119,7 @@
Class<T> targetType) {
List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
for (Import anImport : allImports) {
- if (imports.isImportingProtoDescriptor(anImport)) {
+ if (imports.hasUnresolvedDescriptorUri(anImport)) {
descriptions.addAll(allBuiltInTypes(targetType));
continue;
}
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 c245f9d..ac9b01b 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
@@ -9,7 +9,6 @@
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;
/**
@@ -21,13 +20,24 @@
public class Imports {
/**
- * Indicates whether the URL of the given import is equal to the path of descriptor.proto.
+ * Indicates whether the URI of the given import is equal to the path of descriptor.proto
+ * ("google/protobuf/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}
+ * @return {@code true} if the URI of the given import is equal to the path of descriptor.proto, {@code false}
* otherwise.
*/
- public boolean isImportingProtoDescriptor(Import anImport) {
+ public boolean hasUnresolvedDescriptorUri(Import anImport) {
if (anImport == null) return false;
- return ProtoDescriptor.PATH.equals(anImport.getImportURI());
+ return isUnresolvedDescriptorUri(anImport.getImportURI());
+ }
+
+ /**
+ * Indicates whether the given import URI is equal to the path of descriptor.proto
+ * ("google/protobuf/descriptor.proto").
+ * @param uri the URI to check.
+ * @return {@code true} if the given import URI is equal to the path of descriptor.proto, {@code false} otherwise.
+ */
+ public boolean isUnresolvedDescriptorUri(String uri) {
+ return "google/protobuf/descriptor.proto".equals(uri);
}
}
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 65833f7..a27e34a 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
@@ -60,8 +60,6 @@
}
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);