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); } }