Introduce a base RetraceResult interface.

Change-Id: I85c9fdbd4f000928067bd97ae0386d264e740a1c
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceClassResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceClassResult.java
index 6751a2a..09db8bd 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceClassResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceClassResult.java
@@ -6,12 +6,13 @@
 
 import com.android.tools.r8.Keep;
 import com.android.tools.r8.references.TypeReference;
+import com.android.tools.r8.retrace.RetraceClassResult.Element;
 import java.util.List;
-import java.util.function.Consumer;
-import java.util.stream.Stream;
 
 @Keep
-public interface RetraceClassResult {
+public interface RetraceClassResult extends RetraceResult<Element> {
+
+  boolean hasRetraceResult();
 
   RetraceFieldResult lookupField(String fieldName);
 
@@ -29,14 +30,6 @@
   RetraceFrameResult lookupFrame(
       String methodName, int position, List<TypeReference> formalTypes, TypeReference returnType);
 
-  Stream<Element> stream();
-
-  RetraceClassResult forEach(Consumer<Element> resultConsumer);
-
-  boolean hasRetraceResult();
-
-  boolean isAmbiguous();
-
   @Keep
   interface Element {
 
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceFieldResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceFieldResult.java
index d3b6014..ef52314 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceFieldResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceFieldResult.java
@@ -5,17 +5,10 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.Keep;
-import java.util.function.Consumer;
-import java.util.stream.Stream;
+import com.android.tools.r8.retrace.RetraceFieldResult.Element;
 
 @Keep
-public interface RetraceFieldResult {
-
-  Stream<Element> stream();
-
-  RetraceFieldResult forEach(Consumer<Element> resultConsumer);
-
-  boolean isAmbiguous();
+public interface RetraceFieldResult extends RetraceResult<Element> {
 
   @Keep
   interface Element {
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceFrameResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceFrameResult.java
index b439d94..f390396 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceFrameResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceFrameResult.java
@@ -5,19 +5,12 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.Keep;
+import com.android.tools.r8.retrace.RetraceFrameResult.Element;
 import java.util.List;
 import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-import java.util.stream.Stream;
 
 @Keep
-public interface RetraceFrameResult {
-
-  Stream<Element> stream();
-
-  RetraceFrameResult forEach(Consumer<Element> resultConsumer);
-
-  boolean isAmbiguous();
+public interface RetraceFrameResult extends RetraceResult<Element> {
 
   @Keep
   interface Element {
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceMethodResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceMethodResult.java
index 20c73e3..0a4bb50 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceMethodResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceMethodResult.java
@@ -5,20 +5,13 @@
 package com.android.tools.r8.retrace;
 
 import com.android.tools.r8.Keep;
-import java.util.function.Consumer;
-import java.util.stream.Stream;
+import com.android.tools.r8.retrace.RetraceMethodResult.Element;
 
 @Keep
-public interface RetraceMethodResult {
+public interface RetraceMethodResult extends RetraceResult<Element> {
 
   RetraceFrameResult narrowByPosition(int position);
 
-  Stream<Element> stream();
-
-  RetraceMethodResult forEach(Consumer<Element> resultConsumer);
-
-  boolean isAmbiguous();
-
   @Keep
   interface Element {
 
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceResult.java
new file mode 100644
index 0000000..0fe37a6
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceResult.java
@@ -0,0 +1,34 @@
+// Copyright (c) 2021, 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.retrace;
+
+import com.android.tools.r8.Keep;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+
+/**
+ * Base interface for any retrace result.
+ *
+ * <p>The retracing of any given item may result in ambiguous results. This base type provides the
+ * contract for representing the ambiguity. Concretely an ambiguous result can be mapped over with
+ * each "element" representing one of the non-ambiguous possible retracings. The retrace result can
+ * itself provide methods for providing contextual information to further restrict the ambiguity of
+ * the result.
+ */
+@Keep
+public interface RetraceResult<E> {
+
+  /** Basic operation over 'elements' which represent a possible non-ambiguous retracing. */
+  Stream<E> stream();
+
+  /** A result is ambiguous iff the stream has two or more elements. */
+  default boolean isAmbiguous() {
+    return stream().findFirst().isPresent() && stream().skip(1).findFirst().isPresent();
+  }
+
+  /** Short-hand for iterating the elements. */
+  default void forEach(Consumer<E> action) {
+    stream().forEach(action);
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceSourceFileResult.java b/src/main/java/com/android/tools/r8/retrace/RetraceSourceFileResult.java
index b2d4273..076d4da 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceSourceFileResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceSourceFileResult.java
@@ -6,6 +6,7 @@
 
 import com.android.tools.r8.Keep;
 
+// TODO: This does not seem to be a "result" per say, should this rather be a RetracedSourceFile?
 @Keep
 public interface RetraceSourceFileResult {
 
diff --git a/src/main/java/com/android/tools/r8/retrace/RetracedClass.java b/src/main/java/com/android/tools/r8/retrace/RetracedClass.java
index e66931e..23b5842 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetracedClass.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetracedClass.java
@@ -6,7 +6,6 @@
 
 import com.android.tools.r8.Keep;
 import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.retrace.internal.RetracedTypeImpl;
 
 @Keep
 public interface RetracedClass {
@@ -15,7 +14,7 @@
 
   String getBinaryName();
 
-  RetracedTypeImpl getRetracedType();
+  RetracedType getRetracedType();
 
   ClassReference getClassReference();
 }
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java
index 6bbc26a..5028d84 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java
@@ -22,7 +22,6 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.function.BiFunction;
-import java.util.function.Consumer;
 import java.util.stream.Stream;
 
 public class RetraceClassResultImpl implements RetraceClassResult {
@@ -186,12 +185,6 @@
         mapper);
   }
 
-  @Override
-  public RetraceClassResultImpl forEach(Consumer<Element> resultConsumer) {
-    stream().forEach(resultConsumer);
-    return this;
-  }
-
   private interface ResultConstructor<T, R, D> {
     R create(
         RetraceClassResultImpl classResult,
@@ -200,12 +193,6 @@
         Retracer retracer);
   }
 
-  @Override
-  public boolean isAmbiguous() {
-    // Currently we have no way of producing ambiguous class results.
-    return false;
-  }
-
   public static class ElementImpl implements Element {
 
     private final RetraceClassResultImpl classResult;
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFieldResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFieldResultImpl.java
index 73b7dbd..4a82482 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFieldResultImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFieldResultImpl.java
@@ -13,7 +13,6 @@
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.Pair;
 import java.util.List;
-import java.util.function.Consumer;
 import java.util.stream.Stream;
 
 public class RetraceFieldResultImpl implements RetraceFieldResult {
@@ -79,12 +78,6 @@
   }
 
   @Override
-  public RetraceFieldResultImpl forEach(Consumer<Element> resultConsumer) {
-    stream().forEach(resultConsumer);
-    return this;
-  }
-
-  @Override
   public boolean isAmbiguous() {
     if (memberNamings.size() > 1) {
       return true;
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java
index 341ac8d..47635c7 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java
@@ -21,7 +21,6 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.function.BiConsumer;
-import java.util.function.Consumer;
 import java.util.stream.Stream;
 
 public class RetraceFrameResultImpl implements RetraceFrameResult {
@@ -116,12 +115,6 @@
         obfuscatedPosition);
   }
 
-  @Override
-  public RetraceFrameResultImpl forEach(Consumer<Element> resultConsumer) {
-    stream().forEach(resultConsumer);
-    return this;
-  }
-
   private RetracedMethodImpl getRetracedMethod(
       MethodReference methodReference, MappedRange mappedRange, int obfuscatedPosition) {
     if (mappedRange.minifiedRange == null) {
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceMethodResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceMethodResultImpl.java
index 46d63bc..7922955 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceMethodResultImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceMethodResultImpl.java
@@ -13,7 +13,6 @@
 import com.google.common.collect.ImmutableList;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.function.Consumer;
 import java.util.stream.Stream;
 
 public class RetraceMethodResultImpl implements RetraceMethodResult {
@@ -122,12 +121,6 @@
             });
   }
 
-  @Override
-  public RetraceMethodResultImpl forEach(Consumer<Element> resultConsumer) {
-    stream().forEach(resultConsumer);
-    return this;
-  }
-
   public static class ElementImpl implements RetraceMethodResult.Element {
 
     private final RetracedMethodImpl methodReference;
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceTypeResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceTypeResultImpl.java
index b48d5f3..2ec0529 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceTypeResultImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceTypeResultImpl.java
@@ -6,6 +6,7 @@
 
 import com.android.tools.r8.references.TypeReference;
 import com.android.tools.r8.retrace.RetraceTypeResult;
+import com.android.tools.r8.retrace.RetracedType;
 import com.android.tools.r8.retrace.Retracer;
 import java.util.function.Consumer;
 import java.util.stream.Stream;
@@ -55,14 +56,14 @@
 
   public static class ElementImpl implements RetraceTypeResult.Element {
 
-    private final RetracedTypeImpl retracedType;
+    private final RetracedType retracedType;
 
-    public ElementImpl(RetracedTypeImpl retracedType) {
+    public ElementImpl(RetracedType retracedType) {
       this.retracedType = retracedType;
     }
 
     @Override
-    public RetracedTypeImpl getType() {
+    public RetracedType getType() {
       return retracedType;
     }
   }