Fixed: [ Issue 36 ] Resolution of "Import URIs" does not work if such URI and the resource URI have overlapping folders
https://code.google.com/p/protobuf-dt/issues/detail?id=36
Fixed: [ Issue 37 ] Groups can end with a semicolon
https://code.google.com/p/protobuf-dt/issues/detail?id=37
Fixed: [ Issue 38 ] "extend message" should be allowed inside a message definition
https://code.google.com/p/protobuf-dt/issues/detail?id=38
Fixed: [ Issue 39 ] Message fields can have a default value and deprecation inside a single pair of brackets
https://code.google.com/p/protobuf-dt/issues/detail?id=39
diff --git a/com.google.eclipse.protobuf.test/META-INF/MANIFEST.MF b/com.google.eclipse.protobuf.test/META-INF/MANIFEST.MF
index d9ceabf..646fe3f 100644
--- a/com.google.eclipse.protobuf.test/META-INF/MANIFEST.MF
+++ b/com.google.eclipse.protobuf.test/META-INF/MANIFEST.MF
@@ -9,5 +9,6 @@
org.junit.source;bundle-version="4.8.1",
org.eclipse.xtext.junit;bundle-version="2.0.0",
org.eclipse.xtext.junit4;bundle-version="2.0.0",
- com.google.eclipse.protobuf.junit;bundle-version="1.0.0"
+ com.google.eclipse.protobuf.junit;bundle-version="1.0.0",
+ org.mockito;bundle-version="1.8.5"
Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ImportUriFixerAndResolver_apply_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ImportUriFixerAndResolver_apply_Test.java
deleted file mode 100644
index f5e9a1a..0000000
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ImportUriFixerAndResolver_apply_Test.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.scoping;
-
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.junit.Assert.assertThat;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.xtext.scoping.impl.ImportUriResolver;
-import org.junit.*;
-
-import com.google.eclipse.protobuf.junit.core.XtextRule;
-import com.google.eclipse.protobuf.protobuf.*;
-
-/**
- * Tests for <code>{@link ImportUriFixerAndResolver#apply(EObject)}</code>.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class ImportUriFixerAndResolver_apply_Test {
-
- @Rule public XtextRule xtext = new XtextRule();
-
- private ImportUriFixerAndResolver resolver;
-
- @Before public void setUp() {
- resolver = (ImportUriFixerAndResolver) xtext.getInstanceOf(ImportUriResolver.class);
- }
-
- @Test public void should_fix_import_URI_if_missing_scheme() {
- StringBuilder proto = new StringBuilder();
- proto.append("import \"folder1/test.proto\";");
- Protobuf root = xtext.parse(proto);
- Import anImport = root.getImports().get(0);
- String resolved = resolver.apply(anImport);
- assertThat(resolved, equalTo("platform:/resource/folder1/test.proto"));
- }
-
-
- @Test public void should_not_fix_import_URI_if_not_missing_scheme() {
- StringBuilder proto = new StringBuilder();
- proto.append("import \"platform:/resource/folder1/test.proto\";");
- Protobuf root = xtext.parse(proto);
- Import anImport = root.getImports().get(0);
- String resolved = resolver.apply(anImport);
- assertThat(resolved, equalTo("platform:/resource/folder1/test.proto"));
- }
-}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ImportUriFixer_fixUri_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ImportUriFixer_fixUri_Test.java
new file mode 100644
index 0000000..982eb39
--- /dev/null
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ImportUriFixer_fixUri_Test.java
@@ -0,0 +1,49 @@
+/*
+ * 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.scoping;
+
+import static org.eclipse.emf.common.util.URI.createURI;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+
+import org.eclipse.emf.common.util.URI;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for <code>{@link ImportUriFixer#fixUri(String, URI)}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ImportUriFixer_fixUri_Test {
+
+ private ImportUriFixer fixer;
+ private URI resourceUri;
+
+ @Before public void setUp() {
+ resourceUri = createURI("platform:/resource/testing/src/test.proto");
+ fixer = new ImportUriFixer();
+ }
+
+ @Test public void should_fix_import_URI_if_missing_scheme() {
+ String fixed = fixer.fixUri("folder1/test.proto", resourceUri);
+ assertThat(fixed, equalTo("platform:/resource/testing/src/folder1/test.proto"));
+ }
+
+ @Test public void should_not_fix_import_URI_if_not_missing_scheme() {
+ String importUri = "platform:/resource/testing/src/folder1/test.proto";
+ String fixed = fixer.fixUri(importUri, resourceUri);
+ assertThat(fixed, equalTo(importUri));
+ }
+
+ @Test public void should_fix_import_URI_even_if_overlapping_folders_with_resource_URI() {
+ String fixed = fixer.fixUri("testing/src/folder1/test.proto", resourceUri);
+ assertThat(fixed, equalTo("platform:/resource/testing/src/folder1/test.proto"));
+ }
+}
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 0b1c2c8..5a320c3 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
@@ -47,16 +47,17 @@
'}'(';')?;
MessageElement:
- Type | Property | Group;
+ Type | Property | Group | ExtendMessage;
Group:
modifier=Modifier 'group' name=ID '=' index=INT '{'
elements+=Property*
- '}';
+ '}'(';')?;
Property:
modifier=Modifier type=AbstractTypeReference name=ID '=' index=INT (('[' 'default' '=' default=ValueRef
- ']') | ('[' 'packed' '=' packed=BooleanRef ']') | ('[' 'deprecated' '=' deprecated=BooleanRef ']') )? ';';
+ ']') | ('[' 'packed' '=' packed=BooleanRef ']') | ('[' 'deprecated' '=' deprecated=BooleanRef ']')
+ | ('[' 'default' '=' default=ValueRef ',' 'deprecated' '=' deprecated=BooleanRef ']') )? ';';
enum Modifier:
required
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/Globals.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/Globals.java
index e8e8b26..abda482 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/Globals.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/Globals.java
@@ -87,12 +87,18 @@
addFileOption((Property) e);
continue;
}
- if (e instanceof Enum && "OptimizeMode".equals(e.getName())) {
+ if (isOptimizeModeEnum(e)) {
optimizedMode = (Enum) e;
continue;
}
}
}
+
+ private boolean isOptimizeModeEnum(MessageElement e) {
+ if (!(e instanceof Enum)) return false;
+ Enum anEnum = (Enum) e;
+ return "OptimizeMode".equals(anEnum.getName());
+ }
private Message fileOptionsMessage() {
for (Message m : getAllContentsOfType(root, Message.class))
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ImportUriFixer.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ImportUriFixer.java
new file mode 100644
index 0000000..eec205d
--- /dev/null
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ImportUriFixer.java
@@ -0,0 +1,55 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+package com.google.eclipse.protobuf.scoping;
+
+import java.util.List;
+
+import org.eclipse.emf.common.util.URI;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+class ImportUriFixer {
+
+ static final String PREFIX = "platform:/resource";
+
+ private static final String SEPARATOR = "/";
+
+ /*
+ * The import URI is relative to the file where the import is. Protoc works fine, but the editor doesn't.
+ * In order for the editor to see the import, we need to add to the import URI "platform:resource" and the parent
+ * folder of the file containing the import.
+ *
+ * For example: given the following file hierarchy:
+ *
+ * - protobuf-test (project)
+ * - folder
+ * - proto2.proto
+ * - proto1.proto
+ *
+ * If we import "folder/proto2.proto" into proto1.proto, proto1.proto will compile fine, but the editor will complain.
+ * We need to have the import URI as "platform:/resource/protobuf-test/folder/proto2.proto" for the editor to see it.
+ */
+ String fixUri(String importUri, URI resourceUri) {
+ if (importUri.startsWith(PREFIX)) return importUri;
+ String prefix = uriPrefix(URI.createURI(importUri).segmentsList(), resourceUri);
+ if (importUri.startsWith(prefix)) return importUri;
+ if (!prefix.endsWith(SEPARATOR)) prefix += SEPARATOR;
+ String fixed = prefix + importUri;
+ System.out.println(resourceUri + " : " + importUri + " : " + fixed);
+ return fixed;
+ }
+
+ private String uriPrefix(List<String> importUri, URI resourceUri) {
+ StringBuilder prefix = new StringBuilder();
+ prefix.append(PREFIX);
+ String firstSegment = importUri.get(0);
+ List<String> segments = resourceUri.segmentsList();
+ int end = segments.size() - 1; // ignore file name (at the end of the URI)
+ for (int j = 1; j < end; j++) {
+ if (segments.get(j).equals(firstSegment)) break;
+ prefix.append(SEPARATOR).append(segments.get(j));
+ }
+ return prefix.toString();
+ }
+}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ImportUriFixerAndResolver.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ImportUriFixerAndResolver.java
index 2faf1c5..50a351d 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ImportUriFixerAndResolver.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ImportUriFixerAndResolver.java
@@ -8,13 +8,13 @@
*/
package com.google.eclipse.protobuf.scoping;
-import java.util.List;
+import static com.google.eclipse.protobuf.scoping.ImportUriFixer.PREFIX;
-import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.scoping.impl.ImportUriResolver;
import com.google.eclipse.protobuf.protobuf.Import;
+import com.google.inject.Inject;
/**
* Resolves URIs. This implementation mimics how protoc understands imported file URIs. For example, the URI
@@ -29,8 +29,8 @@
*/
public class ImportUriFixerAndResolver extends ImportUriResolver {
- private static final String PREFIX = "platform:/resource";
-
+ @Inject private ImportUriFixer uriFixer;
+
/**
* Prefix used by EMF for resource URIs: "platform:/resource/".
*/
@@ -47,38 +47,8 @@
return super.apply(from);
}
- /*
- * The import URI is relative to the file where the import is. Protoc works fine, but the editor doesn't.
- * In order for the editor to see the import, we need to add to the import URI "platform:resource" and the parent
- * folder of the file containing the import.
- *
- * For example: given the following file hierarchy:
- *
- * - protobuf-test (project)
- * - folder
- * - proto2.proto
- * - proto1.proto
- *
- * If we import "folder/proto2.proto" into proto1.proto, proto1.proto will compile fine, but the editor will complain.
- * We need to have the import URI as "platform:/resource/protobuf-test/folder/proto2.proto" for the editor to see it.
- */
private void fixUri(Import i) {
- String prefix = uriPrefix(i.eResource().getURI());
- String uri = i.getImportURI();
- if (!uri.startsWith(prefix)) {
- if (!uri.startsWith(prefix)) prefix += "/";
- i.setImportURI(prefix + uri);
- }
- }
-
- private String uriPrefix(URI containerUri) {
- StringBuilder prefix = new StringBuilder();
- prefix.append(PREFIX);
- int start = (containerUri.scheme() == null) ? 0 : 1; // ignore the scheme if present (e.g. "platform")
- List<String> segments = containerUri.segmentsList();
- int end = segments.size() - 1; // ignore file name (at the end of the URI)
- for (int j = start; j < end; j++)
- prefix.append("/").append(segments.get(j));
- return prefix.toString();
+ String fixed = uriFixer.fixUri(i.getImportURI(), i.eResource().getURI());
+ i.setImportURI(fixed);
}
}