[KeepAnno] Refactor base parser interface to unify with declarations

Bug: b/248408342
Change-Id: Ibd9f17dd3216ce07f7ddd2d62548822a013ad9d6
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/ConvertingPropertyParser.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/ConvertingPropertyParser.java
index bbc07f3..e449c88 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/asm/ConvertingPropertyParser.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/ConvertingPropertyParser.java
@@ -45,9 +45,8 @@
   }
 
   @Override
-  public T2 tryParse(String name, Object value) {
-    T1 t1 = parser.tryParse(name, value);
-    return t1 == null ? null : converter.apply(t1);
+  public boolean tryParse(String name, Object value, Consumer<T2> setValue) {
+    return parser.tryParse(name, value, wrap(setValue));
   }
 
   @Override
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/DeclarationParser.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/DeclarationParser.java
new file mode 100644
index 0000000..cc9a74d
--- /dev/null
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/DeclarationParser.java
@@ -0,0 +1,86 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.keepanno.asm;
+
+import java.util.List;
+import java.util.function.Consumer;
+import org.objectweb.asm.AnnotationVisitor;
+
+/** Base for a parser that does not have "properties" as such. */
+public abstract class DeclarationParser<T> implements Parser<T> {
+
+  abstract List<Parser<?>> parsers();
+
+  private void ignore(Object arg) {}
+
+  @Override
+  public boolean isDeclared() {
+    for (Parser<?> parser : parsers()) {
+      if (parser.isDeclared()) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @Override
+  public boolean tryParse(String name, Object value, Consumer<T> setValue) {
+    return tryParse(name, value);
+  }
+
+  @Override
+  public boolean tryParseEnum(String name, String descriptor, String value, Consumer<T> setValue) {
+    return tryParseEnum(name, descriptor, value);
+  }
+
+  @Override
+  public AnnotationVisitor tryParseArray(String name, Consumer<T> setValue) {
+    return tryParseArray(name);
+  }
+
+  @Override
+  public AnnotationVisitor tryParseAnnotation(
+      String name, String descriptor, Consumer<T> setValue) {
+    return tryParseAnnotation(name, descriptor);
+  }
+
+  public boolean tryParse(String name, Object value) {
+    for (Parser<?> parser : parsers()) {
+      if (parser.tryParse(name, value, this::ignore)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public boolean tryParseEnum(String name, String descriptor, String value) {
+    for (Parser<?> parser : parsers()) {
+      if (parser.tryParseEnum(name, descriptor, value, this::ignore)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public AnnotationVisitor tryParseArray(String name) {
+    for (Parser<?> parser : parsers()) {
+      AnnotationVisitor visitor = parser.tryParseArray(name, this::ignore);
+      if (visitor != null) {
+        return visitor;
+      }
+    }
+    return null;
+  }
+
+  public AnnotationVisitor tryParseAnnotation(String name, String descriptor) {
+    for (Parser<?> parser : parsers()) {
+      AnnotationVisitor visitor = parser.tryParseAnnotation(name, descriptor, this::ignore);
+      if (visitor != null) {
+        return visitor;
+      }
+    }
+    return null;
+  }
+}
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReader.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReader.java
index fc4cd2e..c346dbd 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReader.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReader.java
@@ -1189,75 +1189,7 @@
     }
   }
 
-  abstract static class Declaration {
-
-    boolean isDefault() {
-      for (Declaration declaration : declarations()) {
-        if (!declaration.isDefault()) {
-          return false;
-        }
-      }
-      return true;
-    }
-
-    List<Declaration> declarations() {
-      return Collections.emptyList();
-    }
-
-    List<PropertyParser<?, ?>> parsers() {
-      return Collections.emptyList();
-    }
-
-    private void ignore(Object arg) {}
-
-    boolean tryParse(String name, Object value) {
-      for (Declaration declaration : declarations()) {
-        if (declaration.tryParse(name, value)) {
-          return true;
-        }
-      }
-      for (PropertyParser<?, ?> parser : parsers()) {
-        if (parser.tryParse(name, value, this::ignore)) {
-          return true;
-        }
-      }
-      return false;
-    }
-
-    AnnotationVisitor tryParseArray(String name) {
-      for (Declaration declaration : declarations()) {
-        AnnotationVisitor visitor = declaration.tryParseArray(name);
-        if (visitor != null) {
-          return visitor;
-        }
-      }
-      for (PropertyParser<?, ?> parser : parsers()) {
-        AnnotationVisitor visitor = parser.tryParseArray(name, this::ignore);
-        if (visitor != null) {
-          return visitor;
-        }
-      }
-      return null;
-    }
-
-    AnnotationVisitor tryParseAnnotation(String name, String descriptor) {
-      for (Declaration declaration : declarations()) {
-        AnnotationVisitor visitor = declaration.tryParseAnnotation(name, descriptor);
-        if (visitor != null) {
-          return visitor;
-        }
-      }
-      for (PropertyParser<?, ?> parser : parsers()) {
-        AnnotationVisitor visitor = parser.tryParseAnnotation(name, descriptor, this::ignore);
-        if (visitor != null) {
-          return visitor;
-        }
-      }
-      return null;
-    }
-  }
-
-  private static class ClassDeclaration extends Declaration {
+  private static class ClassDeclarationParser extends DeclarationParser<KeepClassItemReference> {
 
     private final ParsingContext parsingContext;
     private final Supplier<UserBindingsHelper> getBindingsHelper;
@@ -1266,9 +1198,9 @@
     private final ClassNameParser classNameParser;
     private final ClassNameParser annotatedByParser;
     private final InstanceOfParser instanceOfParser;
-    private final List<PropertyParser<?, ?>> parsers;
+    private final List<Parser<?>> parsers;
 
-    public ClassDeclaration(
+    public ClassDeclarationParser(
         ParsingContext parsingContext, Supplier<UserBindingsHelper> getBindingsHelper) {
       this.parsingContext = parsingContext.group(Item.classGroup);
       this.getBindingsHelper = getBindingsHelper;
@@ -1297,7 +1229,7 @@
     }
 
     @Override
-    public List<PropertyParser<?, ?>> parsers() {
+    public List<Parser<?>> parsers() {
       return parsers;
     }
 
@@ -1319,11 +1251,11 @@
     }
 
     @Override
-    boolean isDefault() {
-      return !isBindingReferenceDefined() && super.isDefault();
+    public boolean isDeclared() {
+      return isBindingReferenceDefined() || super.isDeclared();
     }
 
-    private KeepClassItemReference getValue() {
+    public KeepClassItemReference getValue() {
       checkAllowedDefinitions();
       if (isBindingReferenceDefined()) {
         return boundClassItemReference;
@@ -1350,7 +1282,7 @@
     }
 
     @Override
-    boolean tryParse(String name, Object value) {
+    public boolean tryParse(String name, Object value) {
       if (name.equals(Item.classFromBinding) && value instanceof String) {
         KeepBindingSymbol symbol = getBindingsHelper.get().resolveUserBinding((String) value);
         setBindingReference(KeepBindingReference.forClass(symbol).toClassItemReference());
@@ -1360,7 +1292,7 @@
     }
   }
 
-  private static class MethodDeclaration extends Declaration {
+  private static class MethodDeclarationParser extends DeclarationParser<KeepMethodPattern> {
 
     private final ParsingContext parsingContext;
     private KeepMethodAccessPattern.Builder accessBuilder = null;
@@ -1369,9 +1301,9 @@
     private final MethodReturnTypeParser returnTypeParser;
     private final MethodParametersParser parametersParser;
 
-    private final List<PropertyParser<?, ?>> parsers;
+    private final List<Parser<?>> parsers;
 
-    private MethodDeclaration(ParsingContext parsingContext) {
+    private MethodDeclarationParser(ParsingContext parsingContext) {
       this.parsingContext = parsingContext;
 
       nameParser = new StringPatternParser(parsingContext.group(Item.methodNameGroup));
@@ -1391,7 +1323,7 @@
     }
 
     @Override
-    List<PropertyParser<?, ?>> parsers() {
+    List<Parser<?>> parsers() {
       return parsers;
     }
 
@@ -1403,11 +1335,11 @@
     }
 
     @Override
-    boolean isDefault() {
-      return accessBuilder == null && builder == null && super.isDefault();
+    public boolean isDeclared() {
+      return accessBuilder != null || builder != null || super.isDeclared();
     }
 
-    private KeepMethodPattern getValue() {
+    public KeepMethodPattern getValue() {
       if (accessBuilder != null) {
         getBuilder().setAccessPattern(accessBuilder.build());
       }
@@ -1425,7 +1357,7 @@
     }
 
     @Override
-    AnnotationVisitor tryParseArray(String name) {
+    public AnnotationVisitor tryParseArray(String name) {
       if (name.equals(Item.methodAccess)) {
         accessBuilder = KeepMethodAccessPattern.builder();
         return new MethodAccessVisitor(parsingContext, accessBuilder);
@@ -1434,16 +1366,16 @@
     }
   }
 
-  private static class FieldDeclaration extends Declaration {
+  private static class FieldDeclarationParser extends DeclarationParser<KeepFieldPattern> {
 
     private final ParsingContext parsingContext;
     private final StringPatternParser nameParser;
     private final FieldTypeParser typeParser;
     private KeepFieldAccessPattern.Builder accessBuilder = null;
     private KeepFieldPattern.Builder builder = null;
-    private final List<PropertyParser<?, ?>> parsers;
+    private final List<Parser<?>> parsers;
 
-    public FieldDeclaration(ParsingContext parsingContext) {
+    public FieldDeclarationParser(ParsingContext parsingContext) {
       this.parsingContext = parsingContext;
       nameParser = new StringPatternParser(parsingContext.group(Item.fieldNameGroup));
       nameParser.setProperty(Item.fieldName, StringProperty.EXACT);
@@ -1458,7 +1390,7 @@
     }
 
     @Override
-    List<PropertyParser<?, ?>> parsers() {
+    public List<Parser<?>> parsers() {
       return parsers;
     }
 
@@ -1470,11 +1402,11 @@
     }
 
     @Override
-    boolean isDefault() {
-      return accessBuilder == null && builder == null;
+    public boolean isDeclared() {
+      return accessBuilder != null || builder != null;
     }
 
-    private KeepFieldPattern getValue() {
+    public KeepFieldPattern getValue() {
       if (accessBuilder != null) {
         getBuilder().setAccessPattern(accessBuilder.build());
       }
@@ -1488,7 +1420,7 @@
     }
 
     @Override
-    AnnotationVisitor tryParseArray(String name) {
+    public AnnotationVisitor tryParseArray(String name) {
       if (name.equals(Item.fieldAccess)) {
         accessBuilder = KeepFieldAccessPattern.builder();
         return new FieldAccessVisitor(parsingContext, accessBuilder);
@@ -1497,32 +1429,34 @@
     }
   }
 
-  private static class MemberDeclaration extends Declaration {
+  private static class MemberDeclarationParser extends DeclarationParser<KeepMemberPattern> {
 
     private final ParsingContext parsingContext;
     private KeepMemberAccessPattern.Builder accessBuilder = null;
-    private final MethodDeclaration methodDeclaration;
-    private final FieldDeclaration fieldDeclaration;
-    private final List<Declaration> declarations;
+    private final MethodDeclarationParser methodDeclaration;
+    private final FieldDeclarationParser fieldDeclaration;
+    private final List<Parser<?>> parsers;
 
-    MemberDeclaration(ParsingContext parsingContext) {
+    MemberDeclarationParser(ParsingContext parsingContext) {
       this.parsingContext = parsingContext.group(Item.memberGroup);
-      methodDeclaration = new MethodDeclaration(parsingContext);
-      fieldDeclaration = new FieldDeclaration(parsingContext);
-      declarations = ImmutableList.of(methodDeclaration, fieldDeclaration);
+      methodDeclaration = new MethodDeclarationParser(parsingContext);
+      fieldDeclaration = new FieldDeclarationParser(parsingContext);
+      parsers = ImmutableList.of(methodDeclaration, fieldDeclaration);
     }
 
     @Override
-    List<Declaration> declarations() {
-      return declarations;
+    public List<Parser<?>> parsers() {
+      return parsers;
     }
 
     @Override
-    public boolean isDefault() {
-      return accessBuilder == null && methodDeclaration.isDefault() && fieldDeclaration.isDefault();
+    public boolean isDeclared() {
+      return accessBuilder != null
+          || methodDeclaration.isDeclared()
+          || fieldDeclaration.isDeclared();
     }
 
-    private KeepMemberPattern getValue() {
+    public KeepMemberPattern getValue() {
       KeepMethodPattern method = methodDeclaration.getValue();
       KeepFieldPattern field = fieldDeclaration.getValue();
       if (accessBuilder != null) {
@@ -1545,7 +1479,7 @@
     }
 
     @Override
-    AnnotationVisitor tryParseArray(String name) {
+    public AnnotationVisitor tryParseArray(String name) {
       if (name.equals(Item.memberAccess)) {
         accessBuilder = KeepMemberAccessPattern.memberBuilder();
         return new MemberAccessVisitor(parsingContext, accessBuilder);
@@ -1558,9 +1492,8 @@
     private final ParsingContext parsingContext;
     private String memberBindingReference = null;
     private ItemKind kind = null;
-    private final ClassDeclaration classDeclaration;
-    private final MemberDeclaration memberDeclaration;
-
+    private final ClassDeclarationParser classDeclaration;
+    private final MemberDeclarationParser memberDeclaration;
 
     public abstract UserBindingsHelper getBindingsHelper();
 
@@ -1570,8 +1503,8 @@
     KeepItemVisitorBase(ParsingContext parsingContext) {
       super(parsingContext);
       this.parsingContext = parsingContext;
-      classDeclaration = new ClassDeclaration(parsingContext, this::getBindingsHelper);
-      memberDeclaration = new MemberDeclaration(parsingContext);
+      classDeclaration = new ClassDeclarationParser(parsingContext, this::getBindingsHelper);
+      memberDeclaration = new MemberDeclarationParser(parsingContext);
     }
 
     public Collection<KeepItemReference> getItemsWithoutBinding() {
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/Parser.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/Parser.java
new file mode 100644
index 0000000..3ca879b
--- /dev/null
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/Parser.java
@@ -0,0 +1,25 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.keepanno.asm;
+
+import java.util.function.Consumer;
+import org.objectweb.asm.AnnotationVisitor;
+
+interface Parser<T> {
+
+  boolean isDeclared();
+
+  default boolean isDefault() {
+    return !isDeclared();
+  }
+
+  boolean tryParse(String name, Object value, Consumer<T> setValue);
+
+  boolean tryParseEnum(String name, String descriptor, String value, Consumer<T> setValue);
+
+  AnnotationVisitor tryParseArray(String name, Consumer<T> setValue);
+
+  AnnotationVisitor tryParseAnnotation(String name, String descriptor, Consumer<T> setValue);
+}
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/PropertyParser.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/PropertyParser.java
index 0fd8a75..8f2de33e 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/asm/PropertyParser.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/PropertyParser.java
@@ -4,35 +4,9 @@
 
 package com.android.tools.r8.keepanno.asm;
 
-import java.util.function.Consumer;
-import org.objectweb.asm.AnnotationVisitor;
-
-public interface PropertyParser<T, P> {
+public interface PropertyParser<T, P> extends Parser<T> {
 
   void setProperty(String name, P property);
 
-  boolean isDeclared();
-
-  default boolean isDefault() {
-    return !isDeclared();
-  }
-
   T getValue();
-
-  T tryParse(String name, Object value);
-
-  default boolean tryParse(String name, Object value, Consumer<T> setValue) {
-    T result = tryParse(name, value);
-    if (result != null) {
-      setValue.accept(result);
-      return true;
-    }
-    return false;
-  }
-
-  boolean tryParseEnum(String name, String descriptor, String value, Consumer<T> setValue);
-
-  AnnotationVisitor tryParseArray(String name, Consumer<T> setValue);
-
-  AnnotationVisitor tryParseAnnotation(String name, String descriptor, Consumer<T> setValue);
 }
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/PropertyParserBase.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/PropertyParserBase.java
index 1ab1fea..0213ef3 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/asm/PropertyParserBase.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/PropertyParserBase.java
@@ -92,17 +92,16 @@
   }
 
   @Override
-  public final T tryParse(String name, Object value) {
+  public final boolean tryParse(String name, Object value, Consumer<T> setValue) {
     P prop = mapping.get(name);
     if (prop != null) {
       try {
-        tryProperty(prop, name, value, wrap(name, unused -> {}));
+        return tryProperty(prop, name, value, wrap(name, setValue));
       } catch (RuntimeException e) {
         throw parsingContext.rethrow(e);
       }
-      return resultValue;
     }
-    return null;
+    return false;
   }
 
   @Override
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/StringPatternParser.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/StringPatternParser.java
index a7b8a3b..f866a90 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/asm/StringPatternParser.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/StringPatternParser.java
@@ -98,6 +98,7 @@
       assert Property.STRING.equals(property);
       if (value instanceof String) {
         setValue.accept((String) value);
+        return true;
       }
       return false;
     }