Fix parsing of marker annotations with optional parens

MOE_MIGRATED_REVID=136738085
diff --git a/java/com/google/turbine/parse/ConstExpressionParser.java b/java/com/google/turbine/parse/ConstExpressionParser.java
index ad6bc06..5cf41b5 100644
--- a/java/com/google/turbine/parse/ConstExpressionParser.java
+++ b/java/com/google/turbine/parse/ConstExpressionParser.java
@@ -38,9 +38,10 @@
   private int position;
   private final Lexer lexer;
 
-  public ConstExpressionParser(Lexer lexer) {
+  public ConstExpressionParser(Lexer lexer, Token token) {
     this.lexer = lexer;
-    eat();
+    this.token = token;
+    this.position = lexer.position();
   }
 
   private static TurbineOperatorKind operator(Token token) {
@@ -533,17 +534,16 @@
     ImmutableList.Builder<Tree.Expression> args = ImmutableList.builder();
     if (token == Token.LPAREN) {
       eat();
-      while (true) {
+      while (token != Token.RPAREN) {
         Tree.Expression expression = expression();
         if (expression == null) {
           throw new AssertionError("invalid annotation expression");
         }
         args.add(expression);
-        if (token == Token.COMMA) {
-          eat();
-          continue;
+        if (token != Token.COMMA) {
+          break;
         }
-        break;
+        eat();
       }
       if (token == Token.RPAREN) {
         eat();
diff --git a/java/com/google/turbine/parse/Parser.java b/java/com/google/turbine/parse/Parser.java
index 83d5e34..5e3171d 100644
--- a/java/com/google/turbine/parse/Parser.java
+++ b/java/com/google/turbine/parse/Parser.java
@@ -16,7 +16,10 @@
 
 package com.google.turbine.parse;
 
+import static com.google.turbine.parse.Token.COMMA;
 import static com.google.turbine.parse.Token.INTERFACE;
+import static com.google.turbine.parse.Token.LPAREN;
+import static com.google.turbine.parse.Token.RPAREN;
 import static com.google.turbine.tree.TurbineModifier.PROTECTED;
 import static com.google.turbine.tree.TurbineModifier.PUBLIC;
 
@@ -642,8 +645,8 @@
         newty = expandDims(ty, dim);
       }
       // TODO(cushon): skip more fields that are definitely non-const
-      Expression init =
-          new ConstExpressionParser(new IteratorLexer(lexer.source(), it)).expression();
+      IteratorLexer lexer = new IteratorLexer(this.lexer.source(), it);
+      Expression init = new ConstExpressionParser(lexer, lexer.next()).expression();
       if (init != null && init.kind() == Tree.Kind.ARRAY_INIT) {
         init = null;
       }
@@ -683,7 +686,7 @@
         break;
       case DEFAULT:
         {
-          ConstExpressionParser cparser = new ConstExpressionParser(lexer);
+          ConstExpressionParser cparser = new ConstExpressionParser(lexer, lexer.next());
           Tree expr = cparser.expression();
           token = cparser.token;
           if (expr == null && token == Token.AT) {
@@ -1081,11 +1084,15 @@
 
     ImmutableList.Builder<Expression> args = ImmutableList.builder();
     if (token == Token.LPAREN) {
-      do {
-        ConstExpressionParser cparser = new ConstExpressionParser(lexer);
+      eat(LPAREN);
+      while (token != RPAREN) {
+        ConstExpressionParser cparser = new ConstExpressionParser(lexer, token);
         args.add(cparser.expression());
         token = cparser.token;
-      } while (token == Token.COMMA);
+        if (!maybe(COMMA)) {
+          break;
+        }
+      }
       eat(Token.RPAREN);
     }
 
diff --git a/javatests/com/google/turbine/binder/BinderErrorTest.java b/javatests/com/google/turbine/binder/BinderErrorTest.java
index e77c75e..0585460 100644
--- a/javatests/com/google/turbine/binder/BinderErrorTest.java
+++ b/javatests/com/google/turbine/binder/BinderErrorTest.java
@@ -39,7 +39,7 @@
   private static final ImmutableList<Path> BOOTCLASSPATH =
       ImmutableList.of(Paths.get(System.getProperty("java.home")).resolve("lib/rt.jar"));
 
-  @Parameters(name = "{index}: {0}")
+  @Parameters
   public static Iterable<Object[]> parameters() {
     String[][][] testCases = {
       {
diff --git a/javatests/com/google/turbine/lower/LowerIntegrationTest.java b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
index 03300d5..712f96b 100644
--- a/javatests/com/google/turbine/lower/LowerIntegrationTest.java
+++ b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
@@ -222,6 +222,7 @@
       "non_const.test",
       "bounds.test",
       "cast_tail.test",
+      "marker.test",
     };
     List<Object[]> tests =
         ImmutableList.copyOf(testCases).stream().map(x -> new Object[] {x}).collect(toList());
diff --git a/javatests/com/google/turbine/lower/testdata/marker.test b/javatests/com/google/turbine/lower/testdata/marker.test
new file mode 100644
index 0000000..9bb9d2e
--- /dev/null
+++ b/javatests/com/google/turbine/lower/testdata/marker.test
@@ -0,0 +1,14 @@
+=== Anno.java ===
+@interface Anno {}
+
+=== Annos.java ===
+@interface Annos {
+  Anno[] value() default {};
+}
+
+=== Test.java ===
+class Test {
+  @Anno() int x;
+  @Annos(@Anno()) int y;
+  @Annos({@Anno(), @Anno()}) int z;
+}
diff --git a/javatests/com/google/turbine/parse/ExpressionParserTest.java b/javatests/com/google/turbine/parse/ExpressionParserTest.java
index 9e1f4ba..7879b9a 100644
--- a/javatests/com/google/turbine/parse/ExpressionParserTest.java
+++ b/javatests/com/google/turbine/parse/ExpressionParserTest.java
@@ -142,10 +142,8 @@
 
   @Test
   public void test() {
-    Tree.Expression expression =
-        new ConstExpressionParser(
-                new StreamLexer(new UnicodeEscapePreprocessor(new SourceFile(null, input))))
-            .expression();
+    StreamLexer lexer = new StreamLexer(new UnicodeEscapePreprocessor(new SourceFile(null, input)));
+    Tree.Expression expression = new ConstExpressionParser(lexer, lexer.next()).expression();
     if (expected == null) {
       assertThat(expression).isNull();
     } else {
diff --git a/javatests/com/google/turbine/parse/ParseErrorTest.java b/javatests/com/google/turbine/parse/ParseErrorTest.java
index fea0d03..9d16520 100644
--- a/javatests/com/google/turbine/parse/ParseErrorTest.java
+++ b/javatests/com/google/turbine/parse/ParseErrorTest.java
@@ -32,9 +32,10 @@
 
   @Test
   public void intBound() {
-    ConstExpressionParser parser =
-        new ConstExpressionParser(
-            new StreamLexer(new UnicodeEscapePreprocessor(new SourceFile("<>", "2147483648"))));
+    StreamLexer lexer =
+        new StreamLexer(
+            new UnicodeEscapePreprocessor(new SourceFile("<>", String.valueOf("2147483648"))));
+    ConstExpressionParser parser = new ConstExpressionParser(lexer, lexer.next());
     try {
       parser.expression();
       fail("expected parsing to fail");
@@ -45,9 +46,10 @@
 
   @Test
   public void hexIntBound() {
-    ConstExpressionParser parser =
-        new ConstExpressionParser(
-            new StreamLexer(new UnicodeEscapePreprocessor(new SourceFile("<>", "0x100000000"))));
+    StreamLexer lexer =
+        new StreamLexer(
+            new UnicodeEscapePreprocessor(new SourceFile("<>", String.valueOf("0x100000000"))));
+    ConstExpressionParser parser = new ConstExpressionParser(lexer, lexer.next());
     try {
       parser.expression();
       fail("expected parsing to fail");