Fixed: [Issue 197] Allow empty statements.
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue197_AllowEmptyStatements_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue197_AllowEmptyStatements_Test.java
new file mode 100644
index 0000000..4b75230
--- /dev/null
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue197_AllowEmptyStatements_Test.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2012 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.bugs;
+
+import static com.google.eclipse.protobuf.junit.core.UnitTestModule.unitTestModule;
+import static com.google.eclipse.protobuf.junit.core.XtextRule.overrideRuntimeModuleWith;
+
+import org.junit.*;
+
+import com.google.eclipse.protobuf.junit.core.XtextRule;
+import com.google.eclipse.protobuf.protobuf.*;
+
+/**
+ * Tests fix for <a href="http://code.google.com/p/protobuf-dt/issues/detail?id=197">Issue 197</a>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class Issue197_AllowEmptyStatements_Test {
+ @Rule public XtextRule xtext = overrideRuntimeModuleWith(unitTestModule());
+
+ // syntax = "proto2";;
+ //
+ // message Person {}
+ @Test public void should_allow_empty_statement_in_syntax() {
+ xtext.find("Person", Message.class);
+ }
+
+ // syntax = "proto2";
+ //
+ // package com.google.proto.test;;
+ //
+ // message Person {}
+ @Test public void should_allow_empty_statement_in_package() {
+ xtext.find("Person", Message.class);
+ }
+
+ // syntax = "proto2";
+ //
+ // import "google/protobuf/descriptor.proto";;
+ //
+ // message Person {}
+ @Test public void should_allow_empty_statement_in_import() {
+ xtext.find("Person", Message.class);
+ }
+
+ // syntax = "proto2";
+ //
+ // option optimize_for = CODE_SIZE;;
+ //
+ // message Person {}
+ @Test public void should_allow_empty_statement_in_option() {
+ xtext.find("Person", Message.class);
+ }
+
+ // syntax = "proto2";
+ //
+ // message Person {
+ // extensions 1000 to max;;
+ // }
+ //
+ // message PhoneNumber {}
+ @Test public void should_allow_empty_statement_in_extension() {
+ xtext.find("PhoneNumber", Message.class);
+ }
+
+ // syntax = "proto2";
+ //
+ // enum Type {
+ // HOME = 0;;
+ // OFFICE = 1;
+ // }
+ @Test public void should_allow_empty_statement_in_literal() {
+ xtext.find("OFFICE", Literal.class);
+ }
+
+ // syntax = "proto2";
+ //
+ // message Person {}
+ //
+ // service Service {
+ // rpc Rpc (Person) returns (Person);;
+ // }
+ //
+ // message PhoneNumber {}
+ @Test public void should_allow_empty_statement_in_rpc() {
+ xtext.find("PhoneNumber", Message.class);
+ }
+}
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/scoping/MultipleDirectoriesFileResolverStrategy_resolveUri_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/scoping/MultipleDirectoriesFileResolverStrategy_resolveUri_Test.java
index 43f4279..d176e4e 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/scoping/MultipleDirectoriesFileResolverStrategy_resolveUri_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/scoping/MultipleDirectoriesFileResolverStrategy_resolveUri_Test.java
@@ -75,8 +75,8 @@
when(directoryPaths.getValue()).thenReturn("${workspace_loc:/src/protos}");
// try the first time as resource platform
when(uris.exists(URI.createURI("platform:/resource/src/protos/imported.proto"))).thenReturn(false);
- when(mapping.directoryLocation("/src/protos")).thenReturn("/usr/local/project/src/protos");
// try again, but in the file system this time
+ when(mapping.directoryLocation("/src/protos")).thenReturn("/usr/local/project/src/protos");
when(uris.exists(URI.createURI(expected))).thenReturn(true);
String resolved = resolver.resolveUri("imported.proto", declaringResourceUri, allPreferences);
assertThat(resolved, equalTo(expected));
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 20dc5c9..3899343 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
@@ -18,13 +18,13 @@
(elements+=ProtobufElement)*;
Syntax:
- 'syntax' '=' name=STRING ';';
+ 'syntax' '=' name=STRING (';')+;
ProtobufElement:
Package | Import | Option | ComplexType | TypeExtension | Service;
Package:
- 'package' name=PackageName ';';
+ 'package' name=PackageName (';')+;
PackageName:
IdOrReservedWord ('.' IdOrReservedWord)*;
@@ -33,13 +33,13 @@
NormalImport | PublicImport | WeakImport;
NormalImport:
- 'import' importURI=STRING ';';
+ 'import' importURI=STRING (';')+;
PublicImport:
- 'import' 'public' importURI=STRING ';';
+ 'import' 'public' importURI=STRING (';')+;
WeakImport:
- 'import' 'weak' importURI=STRING ';';
+ 'import' 'weak' importURI=STRING (';')+;
ComplexType:
Enum | ExtensibleType;
@@ -68,7 +68,7 @@
Option | IndexedElement | ComplexType | TypeExtension | Extensions;
Extensions:
- 'extensions' ranges+=Range (',' ranges+=Range)* ';';
+ 'extensions' ranges+=Range (',' ranges+=Range)* (';')+;
MessageField:
=>modifier=Modifier type=TypeLink name=Name '=' index=(LONG | HEX)
@@ -100,7 +100,7 @@
Literal:
name=Name '=' index=(LONG | HEX)
- ('[' fieldOptions+=FieldOption (',' fieldOptions+=FieldOption)* ']')? ';';
+ ('[' fieldOptions+=FieldOption (',' fieldOptions+=FieldOption)* ']')? (';')+;
terminal HEX returns ecore::ELong:
('-')? '0x' (NUMBER | 'a'..'f' | 'A'..'F')+;
@@ -126,11 +126,11 @@
Rpc:
'rpc' name=Name '(' argType=MessageLink ')' 'returns' '(' returnType=MessageLink ')'
- (('{' options+=Option* '}') (';')? | ';');
+ (('{' options+=Option* '}') (';')? | (';')+);
Stream:
'stream' name=Name '(' clientMessage=MessageLink ',' serverMessage=MessageLink ')'
- (('{' options+=Option* '}') (';')? | ';');
+ (('{' options+=Option* '}') (';')? | (';')+);
Name:
IdOrReservedWord;
@@ -151,11 +151,11 @@
NativeOption | CustomOption;
NativeOption:
- 'option' source=OptionSource '=' value=Value ';';
+ 'option' source=OptionSource '=' value=Value (';')+;
CustomOption:
'option' '(' source=OptionSource ')'
- ('.' fields+=OptionField ('.' fields+=OptionField)*)? '=' value=Value ';';
+ ('.' fields+=OptionField ('.' fields+=OptionField)*)? '=' value=Value (';')+;
FieldOption:
DefaultValueFieldOption | NativeFieldOption | CustomFieldOption;