Support RPC4 stream syntax

Change-Id: Ib0f751960f3ade4066632bc7b69b2c70c8b00f5f
Signed-off-by: Harry Terkelsen <het@google.com>
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/StreamSyntaxTest.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/StreamSyntaxTest.java
new file mode 100644
index 0000000..9df106d
--- /dev/null
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/StreamSyntaxTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014 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 static org.junit.Assert.assertTrue;
+
+import com.google.eclipse.protobuf.junit.core.XtextRule;
+import com.google.eclipse.protobuf.validation.ProtobufJavaValidator;
+import com.google.inject.Inject;
+
+import org.eclipse.emf.common.util.BasicDiagnostic;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Test that the parser correctly handles streaming RPC syntax.
+ */
+public class StreamSyntaxTest {
+  @Rule public XtextRule xtext = overrideRuntimeModuleWith(unitTestModule());
+
+  @Inject private ProtobufJavaValidator validator;
+
+  // syntax = "proto2";
+  //
+  // service Service {
+  //   rpc Foo(Bar) returns (stream Baz) {};
+  // }
+  @Test public void shouldAllowStreamingReturn() {
+    boolean isValid = validator.validate(xtext.root(), new BasicDiagnostic(), null);
+    assertTrue(isValid);
+  }
+
+  // syntax = "proto2";
+  //
+  // service Service {
+  //   rpc Foo(stream Bar) returns (Baz) {};
+  // }
+  @Test public void shouldAllowStreamingArg() {
+    boolean isValid = validator.validate(xtext.root(), new BasicDiagnostic(), null);
+    assertTrue(isValid);
+  }
+
+  // syntax = "proto2";
+  //
+  // service Service {
+  //   rpc Foo(stream Bar) returns (stream Baz) {};
+  // }
+  @Test public void shouldAllowStreamingArgAndReturn() {
+    boolean isValid = validator.validate(xtext.root(), new BasicDiagnostic(), null);
+    assertTrue(isValid);
+  }
+}
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 6ef7ab7..3e0ce2a 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
@@ -144,7 +144,8 @@
   Option | Rpc | Stream;
 
 Rpc:
-  ->'rpc' name=Name '(' argType=MessageLink ')' 'returns' '(' returnType=MessageLink ')'
+  ->'rpc' name=Name '(' (isArgStreaming?='stream')? argType=MessageLink ')'
+  'returns' '(' (isReturnStreaming?='stream')? returnType=MessageLink ')'
   (('{' options+=Option* '}') (';')? | (';')+);
 
 Stream: