Split missing definition info and context into class, field and method

Change-Id: If4455b4ea79ce7045b21bbf42bb040060159ad2a
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingClassInfo.java b/src/main/java/com/android/tools/r8/diagnostic/MissingClassInfo.java
new file mode 100644
index 0000000..41f255a
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/diagnostic/MissingClassInfo.java
@@ -0,0 +1,25 @@
+// 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.diagnostic;
+
+import com.android.tools.r8.Keep;
+import com.android.tools.r8.references.ClassReference;
+
+@Keep
+public interface MissingClassInfo extends MissingDefinitionInfo {
+
+  /** Returns the reference of the missing class. */
+  ClassReference getClassReference();
+
+  @Override
+  default boolean isMissingClass() {
+    return true;
+  }
+
+  @Override
+  default MissingClassInfo asMissingClass() {
+    return this;
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionClassContext.java b/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionClassContext.java
new file mode 100644
index 0000000..1b73b9f
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionClassContext.java
@@ -0,0 +1,25 @@
+// 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.diagnostic;
+
+import com.android.tools.r8.Keep;
+import com.android.tools.r8.references.ClassReference;
+
+@Keep
+public interface MissingDefinitionClassContext extends MissingDefinitionContext {
+
+  /** Returns the reference of the class context. */
+  ClassReference getClassReference();
+
+  @Override
+  default boolean isClassContext() {
+    return true;
+  }
+
+  @Override
+  default MissingDefinitionClassContext asClassContext() {
+    return this;
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionContext.java b/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionContext.java
index d635881..cb5d3b4 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionContext.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionContext.java
@@ -6,28 +6,56 @@
 
 import com.android.tools.r8.Keep;
 import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.FieldReference;
-import com.android.tools.r8.references.MethodReference;
-import java.util.function.Consumer;
 
 /** A context that references a missing definition in the program, classpath, or library. */
 @Keep
 public interface MissingDefinitionContext {
 
-  /** The class context from which a missing definition is referenced. */
-  ClassReference getClassReference();
-
   /** The origin of the context. */
   Origin getOrigin();
 
+  /** Predicate that is true iff this is an instance of {@link MissingDefinitionClassContext}. */
+  default boolean isClassContext() {
+    return false;
+  }
+
+  /** Predicate that is true iff this is an instance of {@link MissingDefinitionFieldContext}. */
+  default boolean isFieldContext() {
+    return false;
+  }
+
+  /** Predicate that is true iff this is an instance of {@link MissingDefinitionMethodContext}. */
+  default boolean isMethodContext() {
+    return false;
+  }
+
   /**
-   * Provides the context in which the missing definition is referenced to {@param
-   * classReferenceConsumer} if the context is a class, to {@param fieldReferenceConsumer} if the
-   * context is a field, and to {@param methodReferenceConsumer} if the context is a method..
+   * Return a non-null {@link MissingDefinitionClassContext} if this type is {@link
+   * MissingDefinitionClassContext}.
+   *
+   * @return this with static type of {@link MissingDefinitionClassContext}.
    */
-  void getReference(
-      Consumer<ClassReference> classReferenceConsumer,
-      Consumer<FieldReference> fieldReferenceConsumer,
-      Consumer<MethodReference> methodReferenceConsumer);
+  default MissingDefinitionClassContext asClassContext() {
+    return null;
+  }
+
+  /**
+   * Return a non-null {@link MissingDefinitionFieldContext} if this type is {@link
+   * MissingDefinitionFieldContext}.
+   *
+   * @return this with static type of {@link MissingDefinitionFieldContext}.
+   */
+  default MissingDefinitionFieldContext asFieldContext() {
+    return null;
+  }
+
+  /**
+   * Return a non-null {@link MissingDefinitionMethodContext} if this type is {@link
+   * MissingDefinitionMethodContext}.
+   *
+   * @return this with static type of {@link MissingDefinitionMethodContext}.
+   */
+  default MissingDefinitionMethodContext asMethodContext() {
+    return null;
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionFieldContext.java b/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionFieldContext.java
new file mode 100644
index 0000000..7564f5a
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionFieldContext.java
@@ -0,0 +1,25 @@
+// 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.diagnostic;
+
+import com.android.tools.r8.Keep;
+import com.android.tools.r8.references.FieldReference;
+
+@Keep
+public interface MissingDefinitionFieldContext extends MissingDefinitionContext {
+
+  /** Returns the reference of the field context. */
+  FieldReference getFieldReference();
+
+  @Override
+  default boolean isFieldContext() {
+    return true;
+  }
+
+  @Override
+  default MissingDefinitionFieldContext asFieldContext() {
+    return this;
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionInfo.java b/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionInfo.java
index fe6d904..c2905ce 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionInfo.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionInfo.java
@@ -5,11 +5,7 @@
 package com.android.tools.r8.diagnostic;
 
 import com.android.tools.r8.Keep;
-import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.FieldReference;
-import com.android.tools.r8.references.MethodReference;
 import java.util.Collection;
-import java.util.function.Consumer;
 
 /**
  * Information about the contexts that references an item that was not part of the compilation unit.
@@ -18,14 +14,55 @@
 public interface MissingDefinitionInfo {
 
   /**
-   * Provides the missing definition to {@param classReferenceConsumer} if the missing definition is
-   * a class, to {@param fieldReferenceConsumer} if the missing definition is a field, and to
-   * {@param methodReferenceConsumer} if the missing definition is a method..
+   * Predicate that is true iff the MissingDefinitionInfo is an instance of {@link
+   * MissingClassInfo}.
    */
-  void getMissingDefinition(
-      Consumer<ClassReference> classReferenceConsumer,
-      Consumer<FieldReference> fieldReferenceConsumer,
-      Consumer<MethodReference> methodReferenceConsumer);
+  default boolean isMissingClass() {
+    return false;
+  }
+
+  /**
+   * Predicate that is true iff the MissingDefinitionInfo is an instance of {@link
+   * MissingFieldInfo}.
+   */
+  default boolean isMissingField() {
+    return false;
+  }
+
+  /**
+   * Predicate that is true iff the MissingDefinitionInfo is an instance of {@link
+   * MissingMethodInfo}.
+   */
+  default boolean isMissingMethod() {
+    return false;
+  }
+
+  /**
+   * Return a non-null {@link MissingClassInfo} if this type is {@link MissingClassInfo}.
+   *
+   * @return this with static type of {@link MissingClassInfo}.
+   */
+  default MissingClassInfo asMissingClass() {
+    return null;
+  }
+
+  /**
+   * Return a non-null {@link MissingFieldInfo} if this type is {@link MissingFieldInfo}.
+   *
+   * @return this with static type of {@link MissingFieldInfo}.
+   */
+  default MissingFieldInfo asMissingField() {
+    return null;
+  }
+
+  /**
+   * Return a non-null {@link MissingMethodInfo} if this type is {@link MissingMethodInfo}.
+   *
+   * @return this with static type of {@link MissingMethodInfo}.
+   */
+  default MissingMethodInfo asMissingMethod() {
+    return null;
+  }
 
   /** The contexts from which this missing definition was referenced. */
   Collection<MissingDefinitionContext> getReferencedFromContexts();
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionMethodContext.java b/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionMethodContext.java
new file mode 100644
index 0000000..315a29c
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/diagnostic/MissingDefinitionMethodContext.java
@@ -0,0 +1,25 @@
+// 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.diagnostic;
+
+import com.android.tools.r8.Keep;
+import com.android.tools.r8.references.MethodReference;
+
+@Keep
+public interface MissingDefinitionMethodContext extends MissingDefinitionContext {
+
+  /** Returns the reference of the method context. */
+  MethodReference getMethodReference();
+
+  @Override
+  default boolean isMethodContext() {
+    return true;
+  }
+
+  @Override
+  default MissingDefinitionMethodContext asMethodContext() {
+    return this;
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingFieldInfo.java b/src/main/java/com/android/tools/r8/diagnostic/MissingFieldInfo.java
new file mode 100644
index 0000000..1ae6df1
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/diagnostic/MissingFieldInfo.java
@@ -0,0 +1,25 @@
+// 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.diagnostic;
+
+import com.android.tools.r8.Keep;
+import com.android.tools.r8.references.FieldReference;
+
+@Keep
+public interface MissingFieldInfo extends MissingDefinitionInfo {
+
+  /** Returns the reference of the missing field. */
+  FieldReference getFieldReference();
+
+  @Override
+  default boolean isMissingField() {
+    return true;
+  }
+
+  @Override
+  default MissingFieldInfo asMissingField() {
+    return this;
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/diagnostic/MissingMethodInfo.java b/src/main/java/com/android/tools/r8/diagnostic/MissingMethodInfo.java
new file mode 100644
index 0000000..3cf8cc0
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/diagnostic/MissingMethodInfo.java
@@ -0,0 +1,25 @@
+// 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.diagnostic;
+
+import com.android.tools.r8.Keep;
+import com.android.tools.r8.references.MethodReference;
+
+@Keep
+public interface MissingMethodInfo extends MissingDefinitionInfo {
+
+  /** Returns the reference of the missing method. */
+  MethodReference getMethodReference();
+
+  @Override
+  default boolean isMissingMethod() {
+    return true;
+  }
+
+  @Override
+  default MissingMethodInfo asMissingMethod() {
+    return this;
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingClassInfo.java b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingClassInfoImpl.java
similarity index 65%
rename from src/main/java/com/android/tools/r8/diagnostic/internal/MissingClassInfo.java
rename to src/main/java/com/android/tools/r8/diagnostic/internal/MissingClassInfoImpl.java
index eddb5ca..b240279 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingClassInfo.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingClassInfoImpl.java
@@ -4,19 +4,17 @@
 
 package com.android.tools.r8.diagnostic.internal;
 
+import com.android.tools.r8.diagnostic.MissingClassInfo;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
 import com.android.tools.r8.diagnostic.MissingDefinitionInfo;
 import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.FieldReference;
-import com.android.tools.r8.references.MethodReference;
 import java.util.Collection;
-import java.util.function.Consumer;
 
-public class MissingClassInfo extends MissingDefinitionInfoBase {
+public class MissingClassInfoImpl extends MissingDefinitionInfoBase implements MissingClassInfo {
 
   private final ClassReference classReference;
 
-  private MissingClassInfo(
+  private MissingClassInfoImpl(
       ClassReference classReference, Collection<MissingDefinitionContext> referencedFromContexts) {
     super(referencedFromContexts);
     this.classReference = classReference;
@@ -27,11 +25,8 @@
   }
 
   @Override
-  public void getMissingDefinition(
-      Consumer<ClassReference> classReferenceConsumer,
-      Consumer<FieldReference> fieldReferenceConsumer,
-      Consumer<MethodReference> methodReferenceConsumer) {
-    classReferenceConsumer.accept(classReference);
+  public ClassReference getClassReference() {
+    return classReference;
   }
 
   public static class Builder extends MissingDefinitionInfoBase.Builder {
@@ -46,7 +41,7 @@
     }
 
     public MissingDefinitionInfo build() {
-      return new MissingClassInfo(classReference, referencedFromContextsBuilder.build());
+      return new MissingClassInfoImpl(classReference, referencedFromContextsBuilder.build());
     }
   }
 }
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionClassContext.java b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionClassContextImpl.java
similarity index 62%
rename from src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionClassContext.java
rename to src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionClassContextImpl.java
index dbd5e5f..7944a1e 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionClassContext.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionClassContextImpl.java
@@ -4,17 +4,16 @@
 
 package com.android.tools.r8.diagnostic.internal;
 
+import com.android.tools.r8.diagnostic.MissingDefinitionClassContext;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.FieldReference;
-import com.android.tools.r8.references.MethodReference;
-import java.util.function.Consumer;
 
-public class MissingDefinitionClassContext extends MissingDefinitionContextBase {
+public class MissingDefinitionClassContextImpl extends MissingDefinitionContextBase
+    implements MissingDefinitionClassContext {
 
   private final ClassReference classReference;
 
-  private MissingDefinitionClassContext(ClassReference classReference, Origin origin) {
+  private MissingDefinitionClassContextImpl(ClassReference classReference, Origin origin) {
     super(origin);
     this.classReference = classReference;
   }
@@ -28,14 +27,6 @@
     return classReference;
   }
 
-  @Override
-  public void getReference(
-      Consumer<ClassReference> classReferenceConsumer,
-      Consumer<FieldReference> fieldReferenceConsumer,
-      Consumer<MethodReference> methodReferenceConsumer) {
-    classReferenceConsumer.accept(classReference);
-  }
-
   public static class Builder extends MissingDefinitionContextBase.Builder<Builder> {
 
     private ClassReference classReference;
@@ -53,9 +44,9 @@
     }
 
     @Override
-    public MissingDefinitionClassContext build() {
+    public MissingDefinitionClassContextImpl build() {
       assert validate();
-      return new MissingDefinitionClassContext(classReference, origin);
+      return new MissingDefinitionClassContextImpl(classReference, origin);
     }
 
     @Override
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionContextUtils.java b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionContextUtils.java
index a19dd7c..74b48c5 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionContextUtils.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionContextUtils.java
@@ -4,31 +4,76 @@
 
 package com.android.tools.r8.diagnostic.internal;
 
+import com.android.tools.r8.diagnostic.MissingDefinitionClassContext;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
+import com.android.tools.r8.diagnostic.MissingDefinitionFieldContext;
+import com.android.tools.r8.diagnostic.MissingDefinitionMethodContext;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.Definition;
 import com.android.tools.r8.graph.ProgramDerivedContext;
+import com.android.tools.r8.utils.FieldReferenceUtils;
+import com.android.tools.r8.utils.MethodReferenceUtils;
+import java.util.function.Consumer;
+import java.util.function.Function;
 
 public class MissingDefinitionContextUtils {
 
+  public static void accept(
+      MissingDefinitionContext missingDefinitionContext,
+      Consumer<MissingDefinitionClassContext> missingDefinitionClassContextConsumer,
+      Consumer<MissingDefinitionFieldContext> missingDefinitionFieldContextConsumer,
+      Consumer<MissingDefinitionMethodContext> missingDefinitionMethodContextConsumer) {
+    if (missingDefinitionContext.isClassContext()) {
+      missingDefinitionClassContextConsumer.accept(missingDefinitionContext.asClassContext());
+    } else if (missingDefinitionContext.isFieldContext()) {
+      missingDefinitionFieldContextConsumer.accept(missingDefinitionContext.asFieldContext());
+    } else {
+      assert missingDefinitionContext.isMethodContext();
+      missingDefinitionMethodContextConsumer.accept(missingDefinitionContext.asMethodContext());
+    }
+  }
+
+  public static <T> T apply(
+      MissingDefinitionContext missingDefinitionContext,
+      Function<MissingDefinitionClassContext, T> missingDefinitionClassContextFn,
+      Function<MissingDefinitionFieldContext, T> missingDefinitionFieldContextFn,
+      Function<MissingDefinitionMethodContext, T> missingDefinitionMethodContextFn) {
+    if (missingDefinitionContext.isClassContext()) {
+      return missingDefinitionClassContextFn.apply(missingDefinitionContext.asClassContext());
+    } else if (missingDefinitionContext.isFieldContext()) {
+      return missingDefinitionFieldContextFn.apply(missingDefinitionContext.asFieldContext());
+    } else {
+      assert missingDefinitionContext.isMethodContext();
+      return missingDefinitionMethodContextFn.apply(missingDefinitionContext.asMethodContext());
+    }
+  }
+
   public static MissingDefinitionContext create(ProgramDerivedContext programDerivedContext) {
     Definition context = programDerivedContext.getContext();
     MissingDefinitionContextBase.Builder<?> builder;
     if (context.isClass()) {
       builder =
-          MissingDefinitionClassContext.builder()
+          MissingDefinitionClassContextImpl.builder()
               .setClassContext(context.asClass().getClassReference());
     } else if (context.isField()) {
       builder =
-          MissingDefinitionFieldContext.builder()
+          MissingDefinitionFieldContextImpl.builder()
               .setFieldContext(context.asField().getFieldReference());
     } else if (context.isMethod()) {
       builder =
-          MissingDefinitionMethodContext.builder()
+          MissingDefinitionMethodContextImpl.builder()
               .setMethodContext(context.asMethod().getMethodReference());
     } else {
       throw new Unreachable();
     }
     return builder.setOrigin(context.getOrigin()).build();
   }
+
+  public static String toSourceString(MissingDefinitionContext missingDefinitionContext) {
+    return MissingDefinitionContextUtils.apply(
+        missingDefinitionContext,
+        classContext -> classContext.getClassReference().getTypeName(),
+        fieldContext -> FieldReferenceUtils.toSourceString(fieldContext.getFieldReference()),
+        methodContext -> MethodReferenceUtils.toSourceString(methodContext.getMethodReference()));
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionFieldContext.java b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionFieldContext.java
deleted file mode 100644
index 6f2960d..0000000
--- a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionFieldContext.java
+++ /dev/null
@@ -1,68 +0,0 @@
-// 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.diagnostic.internal;
-
-import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.FieldReference;
-import com.android.tools.r8.references.MethodReference;
-import java.util.function.Consumer;
-
-public class MissingDefinitionFieldContext extends MissingDefinitionContextBase {
-
-  private final FieldReference fieldReference;
-
-  private MissingDefinitionFieldContext(FieldReference fieldReference, Origin origin) {
-    super(origin);
-    this.fieldReference = fieldReference;
-  }
-
-  public static Builder builder() {
-    return new Builder();
-  }
-
-  @Override
-  public ClassReference getClassReference() {
-    return fieldReference.getHolderClass();
-  }
-
-  @Override
-  public void getReference(
-      Consumer<ClassReference> classReferenceConsumer,
-      Consumer<FieldReference> fieldReferenceConsumer,
-      Consumer<MethodReference> methodReferenceConsumer) {
-    fieldReferenceConsumer.accept(fieldReference);
-  }
-
-  public static class Builder extends MissingDefinitionContextBase.Builder<Builder> {
-
-    private FieldReference fieldReference;
-
-    private Builder() {}
-
-    public Builder setFieldContext(FieldReference fieldReference) {
-      this.fieldReference = fieldReference;
-      return this;
-    }
-
-    @Override
-    Builder self() {
-      return this;
-    }
-
-    @Override
-    public MissingDefinitionFieldContext build() {
-      assert validate();
-      return new MissingDefinitionFieldContext(fieldReference, origin);
-    }
-
-    @Override
-    public boolean validate() {
-      super.validate();
-      assert fieldReference != null;
-      return true;
-    }
-  }
-}
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionFieldContextImpl.java b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionFieldContextImpl.java
new file mode 100644
index 0000000..b9ecf41
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionFieldContextImpl.java
@@ -0,0 +1,59 @@
+// 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.diagnostic.internal;
+
+import com.android.tools.r8.diagnostic.MissingDefinitionFieldContext;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.references.FieldReference;
+
+public class MissingDefinitionFieldContextImpl extends MissingDefinitionContextBase
+    implements MissingDefinitionFieldContext {
+
+  private final FieldReference fieldReference;
+
+  private MissingDefinitionFieldContextImpl(FieldReference fieldReference, Origin origin) {
+    super(origin);
+    this.fieldReference = fieldReference;
+  }
+
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  @Override
+  public FieldReference getFieldReference() {
+    return fieldReference;
+  }
+
+  public static class Builder extends MissingDefinitionContextBase.Builder<Builder> {
+
+    private FieldReference fieldReference;
+
+    private Builder() {}
+
+    public Builder setFieldContext(FieldReference fieldReference) {
+      this.fieldReference = fieldReference;
+      return this;
+    }
+
+    @Override
+    Builder self() {
+      return this;
+    }
+
+    @Override
+    public MissingDefinitionFieldContextImpl build() {
+      assert validate();
+      return new MissingDefinitionFieldContextImpl(fieldReference, origin);
+    }
+
+    @Override
+    public boolean validate() {
+      super.validate();
+      assert fieldReference != null;
+      return true;
+    }
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionInfoUtils.java b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionInfoUtils.java
index 2b0e375..29d008f 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionInfoUtils.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionInfoUtils.java
@@ -4,101 +4,80 @@
 
 package com.android.tools.r8.diagnostic.internal;
 
-import static com.android.tools.r8.utils.ConsumerUtils.emptyConsumer;
-
+import com.android.tools.r8.diagnostic.MissingClassInfo;
 import com.android.tools.r8.diagnostic.MissingDefinitionInfo;
+import com.android.tools.r8.diagnostic.MissingFieldInfo;
+import com.android.tools.r8.diagnostic.MissingMethodInfo;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.FieldReference;
 import com.android.tools.r8.references.MethodReference;
-import com.android.tools.r8.utils.Box;
 import com.android.tools.r8.utils.ClassReferenceUtils;
 import com.android.tools.r8.utils.FieldReferenceUtils;
-import com.android.tools.r8.utils.IntBox;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import java.util.Comparator;
+import java.util.function.Consumer;
 
 public class MissingDefinitionInfoUtils {
 
   private static final Comparator<MissingDefinitionInfo> COMPARATOR =
       (info, other) -> {
-        IntBox result = new IntBox();
-        if (isMissingClassInfo(info)) {
-          ClassReference classReference = getClassReference(info);
-          other.getMissingDefinition(
-              otherClassReference ->
-                  result.set(ClassReferenceUtils.compare(classReference, otherClassReference)),
-              otherFieldReference ->
-                  result.set(
-                      ClassReferenceUtils.compare(
-                          classReference, otherFieldReference.getHolderClass())),
-              otherMethodReference ->
-                  result.set(
-                      ClassReferenceUtils.compare(
-                          classReference, otherMethodReference.getHolderClass())));
-        } else if (isMissingFieldInfo(info)) {
-          FieldReference fieldReference = getFieldReference(info);
-          other.getMissingDefinition(
-              otherClassReference ->
-                  result.set(
-                      ClassReferenceUtils.compare(
-                          fieldReference.getHolderClass(), otherClassReference)),
-              otherFieldReference ->
-                  result.set(FieldReferenceUtils.compare(fieldReference, otherFieldReference)),
-              otherMethodReference ->
-                  result.set(
-                      ClassReferenceUtils.compare(
-                          fieldReference.getHolderClass(), otherMethodReference.getHolderClass())));
-        } else {
-          MethodReference methodReference = getMethodReference(info);
-          other.getMissingDefinition(
-              otherClassReference ->
-                  result.set(
-                      ClassReferenceUtils.compare(
-                          methodReference.getHolderClass(), otherClassReference)),
-              otherFieldReference ->
-                  result.set(
-                      ClassReferenceUtils.compare(
-                          methodReference.getHolderClass(), otherFieldReference.getHolderClass())),
-              otherMethodReference ->
-                  result.set(MethodReferenceUtils.compare(methodReference, otherMethodReference)));
+        if (info.isMissingClass()) {
+          ClassReference classReference = info.asMissingClass().getClassReference();
+          if (other.isMissingClass()) {
+            return ClassReferenceUtils.compare(
+                classReference, other.asMissingClass().getClassReference());
+          }
+          if (other.isMissingField()) {
+            return ClassReferenceUtils.compare(
+                classReference, other.asMissingField().getFieldReference().getHolderClass());
+          }
+          return ClassReferenceUtils.compare(
+              classReference, other.asMissingMethod().getMethodReference().getHolderClass());
         }
-        return result.get();
+        if (info.isMissingField()) {
+          FieldReference fieldReference = info.asMissingField().getFieldReference();
+          if (other.isMissingClass()) {
+            return ClassReferenceUtils.compare(
+                fieldReference.getHolderClass(), other.asMissingClass().getClassReference());
+          }
+          if (other.isMissingField()) {
+            return FieldReferenceUtils.compare(
+                fieldReference, other.asMissingField().getFieldReference());
+          }
+          return ClassReferenceUtils.compare(
+              fieldReference.getHolderClass(),
+              other.asMissingMethod().getMethodReference().getHolderClass());
+        }
+        MethodReference methodReference = info.asMissingMethod().getMethodReference();
+        if (other.isMissingClass()) {
+          return ClassReferenceUtils.compare(
+              methodReference.getHolderClass(), other.asMissingClass().getClassReference());
+        }
+        if (other.isMissingField()) {
+          ClassReferenceUtils.compare(
+              methodReference.getHolderClass(),
+              other.asMissingField().getFieldReference().getHolderClass());
+        }
+        return MethodReferenceUtils.compare(
+            methodReference, other.asMissingMethod().getMethodReference());
       };
 
+  public static void accept(
+      MissingDefinitionInfo missingDefinitionInfo,
+      Consumer<MissingClassInfo> missingClassInfoConsumer,
+      Consumer<MissingFieldInfo> missingFieldInfoConsumer,
+      Consumer<MissingMethodInfo> missingMethodInfoConsumer) {
+    if (missingDefinitionInfo.isMissingClass()) {
+      missingClassInfoConsumer.accept(missingDefinitionInfo.asMissingClass());
+    } else if (missingDefinitionInfo.isMissingField()) {
+      missingFieldInfoConsumer.accept(missingDefinitionInfo.asMissingField());
+    } else {
+      assert missingDefinitionInfo.isMissingMethod();
+      missingMethodInfoConsumer.accept(missingDefinitionInfo.asMissingMethod());
+    }
+  }
+
   public static Comparator<MissingDefinitionInfo> getComparator() {
     return COMPARATOR;
   }
-
-  public static ClassReference getClassReference(MissingDefinitionInfo missingDefinitionInfo) {
-    Box<ClassReference> classReference = new Box<>();
-    missingDefinitionInfo.getMissingDefinition(
-        classReference::set, emptyConsumer(), emptyConsumer());
-    return classReference.get();
-  }
-
-  public static boolean isMissingClassInfo(MissingDefinitionInfo missingDefinitionInfo) {
-    return getClassReference(missingDefinitionInfo) != null;
-  }
-
-  public static FieldReference getFieldReference(MissingDefinitionInfo missingDefinitionInfo) {
-    Box<FieldReference> fieldReference = new Box<>();
-    missingDefinitionInfo.getMissingDefinition(
-        emptyConsumer(), fieldReference::set, emptyConsumer());
-    return fieldReference.get();
-  }
-
-  public static boolean isMissingFieldInfo(MissingDefinitionInfo missingDefinitionInfo) {
-    return getFieldReference(missingDefinitionInfo) != null;
-  }
-
-  public static MethodReference getMethodReference(MissingDefinitionInfo missingDefinitionInfo) {
-    Box<MethodReference> methodReference = new Box<>();
-    missingDefinitionInfo.getMissingDefinition(
-        emptyConsumer(), emptyConsumer(), methodReference::set);
-    return methodReference.get();
-  }
-
-  public static boolean isMissingMethodInfo(MissingDefinitionInfo missingDefinitionInfo) {
-    return getMethodReference(missingDefinitionInfo) != null;
-  }
 }
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionMethodContext.java b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionMethodContext.java
deleted file mode 100644
index 896eef1..0000000
--- a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionMethodContext.java
+++ /dev/null
@@ -1,68 +0,0 @@
-// 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.diagnostic.internal;
-
-import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.FieldReference;
-import com.android.tools.r8.references.MethodReference;
-import java.util.function.Consumer;
-
-public class MissingDefinitionMethodContext extends MissingDefinitionContextBase {
-
-  private final MethodReference methodReference;
-
-  private MissingDefinitionMethodContext(MethodReference methodReference, Origin origin) {
-    super(origin);
-    this.methodReference = methodReference;
-  }
-
-  public static Builder builder() {
-    return new Builder();
-  }
-
-  @Override
-  public ClassReference getClassReference() {
-    return methodReference.getHolderClass();
-  }
-
-  @Override
-  public void getReference(
-      Consumer<ClassReference> classReferenceConsumer,
-      Consumer<FieldReference> fieldReferenceConsumer,
-      Consumer<MethodReference> methodReferenceConsumer) {
-    methodReferenceConsumer.accept(methodReference);
-  }
-
-  public static class Builder extends MissingDefinitionContextBase.Builder<Builder> {
-
-    private MethodReference methodReference;
-
-    private Builder() {}
-
-    public Builder setMethodContext(MethodReference methodReference) {
-      this.methodReference = methodReference;
-      return this;
-    }
-
-    @Override
-    Builder self() {
-      return this;
-    }
-
-    @Override
-    public MissingDefinitionMethodContext build() {
-      assert validate();
-      return new MissingDefinitionMethodContext(methodReference, origin);
-    }
-
-    @Override
-    public boolean validate() {
-      super.validate();
-      assert methodReference != null;
-      return true;
-    }
-  }
-}
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionMethodContextImpl.java b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionMethodContextImpl.java
new file mode 100644
index 0000000..eba8719
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionMethodContextImpl.java
@@ -0,0 +1,59 @@
+// 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.diagnostic.internal;
+
+import com.android.tools.r8.diagnostic.MissingDefinitionMethodContext;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.references.MethodReference;
+
+public class MissingDefinitionMethodContextImpl extends MissingDefinitionContextBase
+    implements MissingDefinitionMethodContext {
+
+  private final MethodReference methodReference;
+
+  private MissingDefinitionMethodContextImpl(MethodReference methodReference, Origin origin) {
+    super(origin);
+    this.methodReference = methodReference;
+  }
+
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  @Override
+  public MethodReference getMethodReference() {
+    return methodReference;
+  }
+
+  public static class Builder extends MissingDefinitionContextBase.Builder<Builder> {
+
+    private MethodReference methodReference;
+
+    private Builder() {}
+
+    public Builder setMethodContext(MethodReference methodReference) {
+      this.methodReference = methodReference;
+      return this;
+    }
+
+    @Override
+    Builder self() {
+      return this;
+    }
+
+    @Override
+    public MissingDefinitionMethodContextImpl build() {
+      assert validate();
+      return new MissingDefinitionMethodContextImpl(methodReference, origin);
+    }
+
+    @Override
+    public boolean validate() {
+      super.validate();
+      assert methodReference != null;
+      return true;
+    }
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionsDiagnosticImpl.java b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionsDiagnosticImpl.java
index 9c1f322..5da21fd 100644
--- a/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionsDiagnosticImpl.java
+++ b/src/main/java/com/android/tools/r8/diagnostic/internal/MissingDefinitionsDiagnosticImpl.java
@@ -86,10 +86,15 @@
 
   private static void writeMissingDefinition(
       StringBuilder builder, MissingDefinitionInfo missingDefinitionInfo) {
-    missingDefinitionInfo.getMissingDefinition(
-        classReference -> builder.append(classReference.getTypeName()),
-        fieldReference -> builder.append(FieldReferenceUtils.toSourceString(fieldReference)),
-        methodReference -> builder.append(MethodReferenceUtils.toSourceString(methodReference)));
+    MissingDefinitionInfoUtils.accept(
+        missingDefinitionInfo,
+        missingClassInfo -> builder.append(missingClassInfo.getClassReference().getTypeName()),
+        missingFieldInfo ->
+            builder.append(
+                FieldReferenceUtils.toSourceString(missingFieldInfo.getFieldReference())),
+        missingMethodInfo ->
+            builder.append(
+                MethodReferenceUtils.toSourceString(missingMethodInfo.getMethodReference())));
     writeReferencedFromSuffix(builder, missingDefinitionInfo);
   }
 
@@ -100,10 +105,18 @@
     Box<MethodReference> methodContext = new Box<>();
     for (MissingDefinitionContext missingDefinitionContext :
         missingDefinitionInfo.getReferencedFromContexts()) {
-      missingDefinitionContext.getReference(
-          classReference -> classContext.setMin(classReference, getClassReferenceComparator()),
-          fieldReference -> fieldContext.setMin(fieldReference, getFieldReferenceComparator()),
-          methodReference -> methodContext.setMin(methodReference, getMethodReferenceComparator()));
+      MissingDefinitionContextUtils.accept(
+          missingDefinitionContext,
+          missingDefinitionClassContext ->
+              classContext.setMin(
+                  missingDefinitionClassContext.getClassReference(), getClassReferenceComparator()),
+          missingDefinitionFieldContext ->
+              fieldContext.setMin(
+                  missingDefinitionFieldContext.getFieldReference(), getFieldReferenceComparator()),
+          missingDefinitionMethodContext ->
+              methodContext.setMin(
+                  missingDefinitionMethodContext.getMethodReference(),
+                  getMethodReferenceComparator()));
     }
     if (fieldContext.isSet()) {
       writeReferencedFromSuffix(
diff --git a/src/main/java/com/android/tools/r8/shaking/MissingClasses.java b/src/main/java/com/android/tools/r8/shaking/MissingClasses.java
index a1cdcca..3670701 100644
--- a/src/main/java/com/android/tools/r8/shaking/MissingClasses.java
+++ b/src/main/java/com/android/tools/r8/shaking/MissingClasses.java
@@ -10,7 +10,7 @@
 import static com.android.tools.r8.utils.collections.IdentityHashSetFromMap.newProgramDerivedContextSet;
 
 import com.android.tools.r8.diagnostic.MissingDefinitionsDiagnostic;
-import com.android.tools.r8.diagnostic.internal.MissingClassInfo;
+import com.android.tools.r8.diagnostic.internal.MissingClassInfoImpl;
 import com.android.tools.r8.diagnostic.internal.MissingDefinitionContextUtils;
 import com.android.tools.r8.diagnostic.internal.MissingDefinitionsDiagnosticImpl;
 import com.android.tools.r8.errors.dontwarn.DontWarnConfiguration;
@@ -161,8 +161,8 @@
           MissingDefinitionsDiagnosticImpl.builder();
       missingClassesToBeReported.forEach(
           (missingClass, programDerivedContexts) -> {
-            MissingClassInfo.Builder missingClassInfoBuilder =
-                MissingClassInfo.builder().setClass(missingClass.asClassReference());
+            MissingClassInfoImpl.Builder missingClassInfoBuilder =
+                MissingClassInfoImpl.builder().setClass(missingClass.asClassReference());
             for (ProgramDerivedContext programDerivedContext : programDerivedContexts) {
               missingClassInfoBuilder.addReferencedFromContext(
                   MissingDefinitionContextUtils.create(programDerivedContext));
diff --git a/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionContextSubject.java b/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionContextSubject.java
index 1138239..4178db4 100644
--- a/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionContextSubject.java
+++ b/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionContextSubject.java
@@ -5,12 +5,12 @@
 package com.android.tools.r8.diagnosticinspector;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
+import com.android.tools.r8.diagnostic.MissingDefinitionClassContext;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.FieldReference;
-import com.android.tools.r8.references.MethodReference;
-import com.android.tools.r8.utils.Box;
+import com.android.tools.r8.diagnostic.MissingDefinitionFieldContext;
+import com.android.tools.r8.diagnostic.MissingDefinitionMethodContext;
 
 public class FoundMissingDefinitionContextSubject {
 
@@ -21,19 +21,24 @@
   }
 
   public FoundMissingDefinitionContextSubject assertEqualTo(
-      MissingDefinitionContext expectedContext) {
-    Box<ClassReference> classReference = new Box<>();
-    Box<FieldReference> fieldReference = new Box<>();
-    Box<MethodReference> methodReference = new Box<>();
-    context.getReference(classReference::set, fieldReference::set, methodReference::set);
-    Box<ClassReference> expectedClassReference = new Box<>();
-    Box<FieldReference> expectedFieldReference = new Box<>();
-    Box<MethodReference> expectedMethodReference = new Box<>();
-    expectedContext.getReference(
-        expectedClassReference::set, expectedFieldReference::set, expectedMethodReference::set);
-    assertEquals(classReference, expectedClassReference);
-    assertEquals(fieldReference, expectedFieldReference);
-    assertEquals(methodReference, expectedMethodReference);
+      MissingDefinitionClassContext expectedContext) {
+    assertTrue(context.isClassContext());
+    assertEquals(expectedContext.getClassReference(), context.asClassContext().getClassReference());
+    return this;
+  }
+
+  public FoundMissingDefinitionContextSubject assertEqualTo(
+      MissingDefinitionFieldContext expectedContext) {
+    assertTrue(context.isFieldContext());
+    assertEquals(expectedContext.getFieldReference(), context.asFieldContext().getFieldReference());
+    return this;
+  }
+
+  public FoundMissingDefinitionContextSubject assertEqualTo(
+      MissingDefinitionMethodContext expectedContext) {
+    assertTrue(context.isMethodContext());
+    assertEquals(
+        expectedContext.getMethodReference(), context.asMethodContext().getMethodReference());
     return this;
   }
 }
diff --git a/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionInfoSubject.java b/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionInfoSubject.java
index f51752f..89a5db5 100644
--- a/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionInfoSubject.java
+++ b/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionInfoSubject.java
@@ -9,6 +9,7 @@
 
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
 import com.android.tools.r8.diagnostic.MissingDefinitionInfo;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionContextUtils;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.FieldReference;
 import com.android.tools.r8.references.MethodReference;
@@ -33,16 +34,20 @@
         .getReferencedFromContexts()
         .forEach(
             context ->
-                context.getReference(
+                MissingDefinitionContextUtils.accept(
+                    context,
                     classContext ->
                         classContexts.put(
-                            classContext, new FoundMissingDefinitionContextSubject(context)),
+                            classContext.getClassReference(),
+                            new FoundMissingDefinitionContextSubject(context)),
                     fieldContext ->
                         fieldContexts.put(
-                            fieldContext, new FoundMissingDefinitionContextSubject(context)),
+                            fieldContext.getFieldReference(),
+                            new FoundMissingDefinitionContextSubject(context)),
                     methodContext ->
                         methodContexts.put(
-                            methodContext, new FoundMissingDefinitionContextSubject(context))));
+                            methodContext.getMethodReference(),
+                            new FoundMissingDefinitionContextSubject(context))));
   }
 
   public FoundMissingDefinitionInfoSubject assertExactContexts(
@@ -50,21 +55,25 @@
     assertEquals(expectedContexts.size(), missingDefinitionInfo.getReferencedFromContexts().size());
     expectedContexts.forEach(
         expectedContext ->
-            expectedContext.getReference(
-                classContext -> {
-                  FoundMissingDefinitionContextSubject subject = classContexts.get(classContext);
+            MissingDefinitionContextUtils.accept(
+                expectedContext,
+                expectedClassContext -> {
+                  FoundMissingDefinitionContextSubject subject =
+                      classContexts.get(expectedClassContext.getClassReference());
                   assertNotNull(subject);
-                  subject.assertEqualTo(expectedContext);
+                  subject.assertEqualTo(expectedClassContext);
                 },
-                fieldContext -> {
-                  FoundMissingDefinitionContextSubject subject = fieldContexts.get(fieldContext);
+                expectedFieldContext -> {
+                  FoundMissingDefinitionContextSubject subject =
+                      fieldContexts.get(expectedFieldContext.getFieldReference());
                   assertNotNull(subject);
-                  subject.assertEqualTo(expectedContext);
+                  subject.assertEqualTo(expectedFieldContext);
                 },
-                methodContext -> {
-                  FoundMissingDefinitionContextSubject subject = methodContexts.get(methodContext);
+                expectedMethodContext -> {
+                  FoundMissingDefinitionContextSubject subject =
+                      methodContexts.get(expectedMethodContext.getMethodReference());
                   assertNotNull(subject);
-                  subject.assertEqualTo(expectedContext);
+                  subject.assertEqualTo(expectedMethodContext);
                 }));
     return this;
   }
diff --git a/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionsDiagnosticSubject.java b/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionsDiagnosticSubject.java
index ac63c98..84e3f4b 100644
--- a/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionsDiagnosticSubject.java
+++ b/src/test/java/com/android/tools/r8/diagnosticinspector/FoundMissingDefinitionsDiagnosticSubject.java
@@ -4,12 +4,12 @@
 
 package com.android.tools.r8.diagnosticinspector;
 
-import static com.android.tools.r8.utils.ConsumerUtils.emptyConsumer;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.ThrowableConsumer;
+import com.android.tools.r8.diagnostic.MissingClassInfo;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
 import com.android.tools.r8.diagnostic.MissingDefinitionInfo;
 import com.android.tools.r8.diagnostic.MissingDefinitionsDiagnostic;
@@ -23,18 +23,16 @@
 public class FoundMissingDefinitionsDiagnosticSubject
     extends FoundDiagnosticSubject<MissingDefinitionsDiagnostic> {
 
-  private final Map<ClassReference, MissingDefinitionInfo> missingClasses = new HashMap<>();
+  private final Map<ClassReference, MissingClassInfo> missingClasses = new HashMap<>();
 
   public FoundMissingDefinitionsDiagnosticSubject(MissingDefinitionsDiagnostic diagnostic) {
     super(diagnostic);
-    diagnostic
-        .getMissingDefinitions()
+    diagnostic.getMissingDefinitions().stream()
+        .filter(MissingDefinitionInfo::isMissingClass)
+        .map(MissingDefinitionInfo::asMissingClass)
         .forEach(
-            missingDefinitionInfo ->
-                missingDefinitionInfo.getMissingDefinition(
-                    classReference -> missingClasses.put(classReference, missingDefinitionInfo),
-                    emptyConsumer(),
-                    emptyConsumer()));
+            missingClassInfo ->
+                missingClasses.put(missingClassInfo.getClassReference(), missingClassInfo));
   }
 
   public FoundMissingDefinitionsDiagnosticSubject assertHasMessage(String expectedMessage) {
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromCatchHandlerTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromCatchHandlerTest.java
index d6f07f2..f45220d 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromCatchHandlerTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromCatchHandlerTest.java
@@ -8,14 +8,14 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromCatchHandlerTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromCheckCastTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromCheckCastTest.java
index 461d701..37df585 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromCheckCastTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromCheckCastTest.java
@@ -8,14 +8,14 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromCheckCastTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromClassAnnotationTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromClassAnnotationTest.java
index f273787..d114dc0 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromClassAnnotationTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromClassAnnotationTest.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import org.junit.Test;
@@ -18,7 +18,7 @@
 public class MissingClassReferencedFromClassAnnotationTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContext.builder()
+      MissingDefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromClassAnnotationWithDataTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromClassAnnotationWithDataTest.java
index 3b6c4c4..10663fa 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromClassAnnotationWithDataTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromClassAnnotationWithDataTest.java
@@ -10,7 +10,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
 import com.android.tools.r8.references.Reference;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -19,7 +19,7 @@
 public class MissingClassReferencedFromClassAnnotationWithDataTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContext.builder()
+      MissingDefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromConstClassTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromConstClassTest.java
index 497b698..94550b8 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromConstClassTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromConstClassTest.java
@@ -8,14 +8,14 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromConstClassTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromEnclosingMethodAttributeTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromEnclosingMethodAttributeTest.java
index fe6f996..40408ee 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromEnclosingMethodAttributeTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromEnclosingMethodAttributeTest.java
@@ -12,7 +12,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.BooleanUtils;
@@ -23,7 +23,7 @@
 public class MissingClassReferencedFromEnclosingMethodAttributeTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContext.builder()
+      MissingDefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(getMainClass()))
           .setOrigin(getOrigin(getMainClass()))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromFieldAnnotationTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromFieldAnnotationTest.java
index 57fe23a..7638885 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromFieldAnnotationTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromFieldAnnotationTest.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContextImpl;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.FieldReferenceUtils;
@@ -19,7 +19,7 @@
 public class MissingClassReferencedFromFieldAnnotationTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionFieldContext.builder()
+      MissingDefinitionFieldContextImpl.builder()
           .setFieldContext(FieldReferenceUtils.fieldFromField(Main.class, "FIELD"))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromImplementsClauseTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromImplementsClauseTest.java
index cb9533f..51da805 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromImplementsClauseTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromImplementsClauseTest.java
@@ -9,7 +9,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import org.junit.Test;
@@ -17,7 +17,7 @@
 public class MissingClassReferencedFromImplementsClauseTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContext.builder()
+      MissingDefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInnerClassAttributeTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInnerClassAttributeTest.java
index 2099527..f421eb1 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInnerClassAttributeTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInnerClassAttributeTest.java
@@ -12,7 +12,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.BooleanUtils;
@@ -23,7 +23,7 @@
 public class MissingClassReferencedFromInnerClassAttributeTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContext.builder()
+      MissingDefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceGetToExistingFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceGetToExistingFieldTest.java
index 334bdcb..1ce5f9f 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceGetToExistingFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceGetToExistingFieldTest.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContextImpl;
 import com.android.tools.r8.utils.FieldReferenceUtils;
 import org.junit.Test;
 
@@ -20,7 +20,7 @@
     extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionFieldContext.builder()
+      MissingDefinitionFieldContextImpl.builder()
           .setFieldContext(FieldReferenceUtils.fieldFromField(Main.class, "field"))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceGetToMissingFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceGetToMissingFieldTest.java
index b500f0a..f367fed 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceGetToMissingFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceGetToMissingFieldTest.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
@@ -20,7 +20,7 @@
     extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceOfTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceOfTest.java
index 98ab16d..7ec1e09 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceOfTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstanceOfTest.java
@@ -8,14 +8,14 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromInstanceOfTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstancePutToExistingFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstancePutToExistingFieldTest.java
index 5813bbc..1f0e5a7 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstancePutToExistingFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstancePutToExistingFieldTest.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContextImpl;
 import com.android.tools.r8.utils.FieldReferenceUtils;
 import org.junit.Test;
 
@@ -20,7 +20,7 @@
     extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionFieldContext.builder()
+      MissingDefinitionFieldContextImpl.builder()
           .setFieldContext(FieldReferenceUtils.fieldFromField(Main.class, "field"))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstancePutToMissingFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstancePutToMissingFieldTest.java
index b1d2cb9..b4dd5a1 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstancePutToMissingFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInstancePutToMissingFieldTest.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
@@ -20,7 +20,7 @@
     extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToAbsentMethodParameterTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToAbsentMethodParameterTest.java
index 4d44c39..31e1942 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToAbsentMethodParameterTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToAbsentMethodParameterTest.java
@@ -10,8 +10,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
-import com.android.tools.r8.missingclasses.MissingClassReferencedFromNestMemberAttributeTest.Main;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import com.google.common.collect.ImmutableList;
 import java.io.IOException;
@@ -26,7 +25,7 @@
     extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToAbsentMethodReturnTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToAbsentMethodReturnTest.java
index 24acc36..4c62ad2 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToAbsentMethodReturnTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToAbsentMethodReturnTest.java
@@ -10,7 +10,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import com.google.common.collect.ImmutableList;
 import java.io.IOException;
@@ -25,7 +25,7 @@
     extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToPresentMethodParameterTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToPresentMethodParameterTest.java
index f0a310d..28c1a79 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToPresentMethodParameterTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToPresentMethodParameterTest.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
@@ -20,7 +20,7 @@
     extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(
               MethodReferenceUtils.methodFromMethod(Main.class, "get", MissingClass.class))
           .setOrigin(getOrigin(Main.class))
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToPresentMethodReturnTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToPresentMethodReturnTest.java
index a6025ad..396117f 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToPresentMethodReturnTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromInvokeVirtualToPresentMethodReturnTest.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
@@ -20,7 +20,7 @@
     extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.methodFromMethod(Main.class, "get"))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptFieldTest.java
index ff5b1f1..c212d86 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptFieldTest.java
@@ -9,7 +9,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContextImpl;
 import com.android.tools.r8.utils.FieldReferenceUtils;
 import org.junit.Test;
 
@@ -17,7 +17,7 @@
 public class MissingClassReferencedFromKeptFieldTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionFieldContext.builder()
+      MissingDefinitionFieldContextImpl.builder()
           .setFieldContext(FieldReferenceUtils.fieldFromField(Main.class, "FIELD"))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptMethodParameterTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptMethodParameterTest.java
index 2cfc56f..fc2d8d3 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptMethodParameterTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptMethodParameterTest.java
@@ -9,7 +9,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
@@ -17,7 +17,7 @@
 public class MissingClassReferencedFromKeptMethodParameterTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(
               MethodReferenceUtils.methodFromMethod(Main.class, "get", MissingClass.class))
           .setOrigin(getOrigin(Main.class))
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptMethodReturnTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptMethodReturnTest.java
index 806c5de..6dc3edb 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptMethodReturnTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromKeptMethodReturnTest.java
@@ -9,7 +9,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
@@ -17,7 +17,7 @@
 public class MissingClassReferencedFromKeptMethodReturnTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.methodFromMethod(Main.class, "get"))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryInstanceFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryInstanceFieldTest.java
index 80cb5f1..860bce2 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryInstanceFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryInstanceFieldTest.java
@@ -12,14 +12,14 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContextImpl;
 import com.android.tools.r8.utils.FieldReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromLibraryInstanceFieldTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionFieldContext.builder()
+      MissingDefinitionFieldContextImpl.builder()
           .setFieldContext(FieldReferenceUtils.fieldFromField(Library.class, "field"))
           .setOrigin(getOrigin(Library.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryStaticFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryStaticFieldTest.java
index b96c380..c5c7950 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryStaticFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryStaticFieldTest.java
@@ -12,14 +12,14 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContextImpl;
 import com.android.tools.r8.utils.FieldReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromLibraryStaticFieldTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionFieldContext.builder()
+      MissingDefinitionFieldContextImpl.builder()
           .setFieldContext(FieldReferenceUtils.fieldFromField(Library.class, "field"))
           .setOrigin(getOrigin(Library.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryVirtualMethodParameterTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryVirtualMethodParameterTest.java
index da99987..4a56add 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryVirtualMethodParameterTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryVirtualMethodParameterTest.java
@@ -12,8 +12,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
-import com.android.tools.r8.missingclasses.MissingClassReferencedFromLibraryVirtualMethodReturnTest.Library;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
@@ -21,7 +20,7 @@
     extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(
               MethodReferenceUtils.methodFromMethod(Library.class, "method", MissingClass.class))
           .setOrigin(getOrigin(Library.class))
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryVirtualMethodReturnTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryVirtualMethodReturnTest.java
index 1ffea31..5c627ef 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryVirtualMethodReturnTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromLibraryVirtualMethodReturnTest.java
@@ -12,7 +12,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
@@ -20,7 +20,7 @@
     extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.methodFromMethod(Library.class, "method"))
           .setOrigin(getOrigin(Library.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromMethodAnnotationTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromMethodAnnotationTest.java
index 1ccf46b..5130304 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromMethodAnnotationTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromMethodAnnotationTest.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.MethodReferenceUtils;
@@ -19,7 +19,7 @@
 public class MissingClassReferencedFromMethodAnnotationTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNestHostAttributeTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNestHostAttributeTest.java
index 2f52a89..194e12d 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNestHostAttributeTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNestHostAttributeTest.java
@@ -10,7 +10,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
 import com.android.tools.r8.missingclasses.MissingClassReferencedFromNestHostAttributeTest.MissingClass.Main;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
@@ -22,7 +22,7 @@
 public class MissingClassReferencedFromNestHostAttributeTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContext.builder()
+      MissingDefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNestMemberAttributeTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNestMemberAttributeTest.java
index 3d5e097..540620e 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNestMemberAttributeTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNestMemberAttributeTest.java
@@ -10,7 +10,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import com.google.common.collect.ImmutableList;
@@ -21,7 +21,7 @@
 public class MissingClassReferencedFromNestMemberAttributeTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContext.builder()
+      MissingDefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNewArrayTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNewArrayTest.java
index c177aa3..003b28e 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNewArrayTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNewArrayTest.java
@@ -8,14 +8,14 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromNewArrayTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNewInstanceTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNewInstanceTest.java
index 1324622..ee919b2 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNewInstanceTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromNewInstanceTest.java
@@ -8,14 +8,14 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromNewInstanceTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromOuterClassAttributeTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromOuterClassAttributeTest.java
index 4cbcd58..21d5683 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromOuterClassAttributeTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromOuterClassAttributeTest.java
@@ -12,7 +12,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
 import com.android.tools.r8.missingclasses.MissingClassReferencedFromOuterClassAttributeTest.MissingClass.Main;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
@@ -24,7 +24,7 @@
 public class MissingClassReferencedFromOuterClassAttributeTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContext.builder()
+      MissingDefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromParameterAnnotationTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromParameterAnnotationTest.java
index 05dbb19..a5b5432 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromParameterAnnotationTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromParameterAnnotationTest.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.MethodReferenceUtils;
@@ -19,7 +19,7 @@
 public class MissingClassReferencedFromParameterAnnotationTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticGetToExistingFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticGetToExistingFieldTest.java
index f301172..332da9c 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticGetToExistingFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticGetToExistingFieldTest.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContextImpl;
 import com.android.tools.r8.utils.FieldReferenceUtils;
 import org.junit.Test;
 
@@ -19,7 +19,7 @@
 public class MissingClassReferencedFromStaticGetToExistingFieldTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionFieldContext.builder()
+      MissingDefinitionFieldContextImpl.builder()
           .setFieldContext(FieldReferenceUtils.fieldFromField(Main.class, "FIELD"))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticGetToMissingFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticGetToMissingFieldTest.java
index dbd1403..9028167 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticGetToMissingFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticGetToMissingFieldTest.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
@@ -19,7 +19,7 @@
 public class MissingClassReferencedFromStaticGetToMissingFieldTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticPutToExistingFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticPutToExistingFieldTest.java
index 17135af..cbbd217 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticPutToExistingFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticPutToExistingFieldTest.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionFieldContextImpl;
 import com.android.tools.r8.utils.FieldReferenceUtils;
 import org.junit.Test;
 
@@ -19,7 +19,7 @@
 public class MissingClassReferencedFromStaticPutToExistingFieldTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionFieldContext.builder()
+      MissingDefinitionFieldContextImpl.builder()
           .setFieldContext(FieldReferenceUtils.fieldFromField(Main.class, "FIELD"))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticPutToMissingFieldTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticPutToMissingFieldTest.java
index 593345d..e1ba4c6 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticPutToMissingFieldTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromStaticPutToMissingFieldTest.java
@@ -8,7 +8,7 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
@@ -19,7 +19,7 @@
 public class MissingClassReferencedFromStaticPutToMissingFieldTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromSuperClassTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromSuperClassTest.java
index 6462a14..79cff47 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromSuperClassTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromSuperClassTest.java
@@ -9,14 +9,14 @@
 import com.android.tools.r8.TestDiagnosticMessages;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionClassContextImpl;
 import com.android.tools.r8.references.Reference;
 import org.junit.Test;
 
 public class MissingClassReferencedFromSuperClassTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionClassContext.builder()
+      MissingDefinitionClassContextImpl.builder()
           .setClassContext(Reference.classFromClass(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromThrowsClauseTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromThrowsClauseTest.java
index 90349ab..275e6f2 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromThrowsClauseTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromThrowsClauseTest.java
@@ -9,14 +9,14 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestShrinkerBuilder;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import org.junit.Test;
 
 public class MissingClassReferencedFromThrowsClauseTest extends MissingClassesTestBase {
 
   private static final MissingDefinitionContext referencedFrom =
-      MissingDefinitionMethodContext.builder()
+      MissingDefinitionMethodContextImpl.builder()
           .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
           .setOrigin(getOrigin(Main.class))
           .build();
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUnusedLambdaParameterTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUnusedLambdaParameterTest.java
index 8015ac4..31ca7d1 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUnusedLambdaParameterTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUnusedLambdaParameterTest.java
@@ -12,7 +12,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import com.google.common.collect.ImmutableList;
@@ -22,7 +22,7 @@
 
   private static final MissingDefinitionContext[] referencedFrom =
       new MissingDefinitionContext[] {
-        MissingDefinitionMethodContext.builder()
+        MissingDefinitionMethodContextImpl.builder()
             .setMethodContext(
                 Reference.method(
                     Reference.classFromClass(Main.class),
@@ -31,7 +31,7 @@
                     null))
             .setOrigin(getOrigin(Main.class))
             .build(),
-        MissingDefinitionMethodContext.builder()
+        MissingDefinitionMethodContextImpl.builder()
             .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
             .setOrigin(getOrigin(Main.class))
             .build(),
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUnusedLambdaReturnTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUnusedLambdaReturnTest.java
index edaf71c..8859780 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUnusedLambdaReturnTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUnusedLambdaReturnTest.java
@@ -12,7 +12,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import java.util.Collections;
@@ -22,7 +22,7 @@
 
   private static final MissingDefinitionContext[] referencedFrom =
       new MissingDefinitionContext[] {
-        MissingDefinitionMethodContext.builder()
+        MissingDefinitionMethodContextImpl.builder()
             .setMethodContext(
                 Reference.method(
                     Reference.classFromClass(Main.class),
@@ -31,7 +31,7 @@
                     Reference.classFromClass(MissingClass.class)))
             .setOrigin(getOrigin(Main.class))
             .build(),
-        MissingDefinitionMethodContext.builder()
+        MissingDefinitionMethodContextImpl.builder()
             .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
             .setOrigin(getOrigin(Main.class))
             .build(),
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUsedLambdaParameterTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUsedLambdaParameterTest.java
index 7d0c68f..a9ece97 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUsedLambdaParameterTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUsedLambdaParameterTest.java
@@ -10,7 +10,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import com.google.common.collect.ImmutableList;
@@ -20,12 +20,12 @@
 
   private final MissingDefinitionContext[] referencedFrom =
       new MissingDefinitionContext[] {
-        MissingDefinitionMethodContext.builder()
+        MissingDefinitionMethodContextImpl.builder()
             .setMethodContext(
                 MethodReferenceUtils.methodFromMethod(I.class, "m", MissingClass.class))
             .setOrigin(getOrigin(I.class))
             .build(),
-        MissingDefinitionMethodContext.builder()
+        MissingDefinitionMethodContextImpl.builder()
             .setMethodContext(
                 Reference.method(
                     Reference.classFromClass(Main.class),
@@ -34,7 +34,7 @@
                     null))
             .setOrigin(getOrigin(Main.class))
             .build(),
-        MissingDefinitionMethodContext.builder()
+        MissingDefinitionMethodContextImpl.builder()
             .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
             .setOrigin(getOrigin(Main.class))
             .build()
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUsedLambdaReturnTest.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUsedLambdaReturnTest.java
index d88f511..ba46bfc 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUsedLambdaReturnTest.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassReferencedFromUsedLambdaReturnTest.java
@@ -10,7 +10,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
-import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionMethodContextImpl;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.utils.MethodReferenceUtils;
 import java.util.Collections;
@@ -20,11 +20,11 @@
 
   private final MissingDefinitionContext[] referencedFrom =
       new MissingDefinitionContext[] {
-        MissingDefinitionMethodContext.builder()
+        MissingDefinitionMethodContextImpl.builder()
             .setMethodContext(MethodReferenceUtils.methodFromMethod(I.class, "m"))
             .setOrigin(getOrigin(I.class))
             .build(),
-        MissingDefinitionMethodContext.builder()
+        MissingDefinitionMethodContextImpl.builder()
             .setMethodContext(
                 Reference.method(
                     Reference.classFromClass(Main.class),
@@ -33,7 +33,7 @@
                     Reference.classFromClass(MissingClass.class)))
             .setOrigin(getOrigin(Main.class))
             .build(),
-        MissingDefinitionMethodContext.builder()
+        MissingDefinitionMethodContextImpl.builder()
             .setMethodContext(MethodReferenceUtils.mainMethod(Main.class))
             .setOrigin(getOrigin(Main.class))
             .build()
diff --git a/src/test/java/com/android/tools/r8/missingclasses/MissingClassesTestBase.java b/src/test/java/com/android/tools/r8/missingclasses/MissingClassesTestBase.java
index e1a5554..f9941c0 100644
--- a/src/test/java/com/android/tools/r8/missingclasses/MissingClassesTestBase.java
+++ b/src/test/java/com/android/tools/r8/missingclasses/MissingClassesTestBase.java
@@ -14,12 +14,10 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.diagnostic.MissingDefinitionContext;
+import com.android.tools.r8.diagnostic.internal.MissingDefinitionContextUtils;
 import com.android.tools.r8.references.ClassReference;
 import com.android.tools.r8.references.Reference;
-import com.android.tools.r8.utils.Box;
-import com.android.tools.r8.utils.FieldReferenceUtils;
 import com.android.tools.r8.utils.InternalOptions.TestingOptions;
-import com.android.tools.r8.utils.MethodReferenceUtils;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.List;
@@ -107,17 +105,12 @@
   void inspectDiagnosticsWithIgnoreWarnings(
       TestDiagnosticMessages diagnostics, MissingDefinitionContext... referencedFrom) {
     assertTrue(referencedFrom.length > 0);
-    Box<String> referencedFromSourceString = new Box<>();
-    referencedFrom[0].getReference(
-        classReference -> referencedFromSourceString.set(classReference.getTypeName()),
-        fieldReference ->
-            referencedFromSourceString.set(FieldReferenceUtils.toSourceString(fieldReference)),
-        methodReference ->
-            referencedFromSourceString.set(MethodReferenceUtils.toSourceString(methodReference)));
     inspectDiagnosticsWithIgnoreWarnings(
         diagnostics,
         referencedFrom,
-        getExpectedDiagnosticMessage(referencedFromSourceString.get(), referencedFrom.length));
+        getExpectedDiagnosticMessage(
+            MissingDefinitionContextUtils.toSourceString(referencedFrom[0]),
+            referencedFrom.length));
   }
 
   void inspectDiagnosticsWithIgnoreWarnings(
@@ -143,17 +136,12 @@
   void inspectDiagnosticsWithNoRules(
       TestDiagnosticMessages diagnostics, MissingDefinitionContext... referencedFrom) {
     assertTrue(referencedFrom.length > 0);
-    Box<String> referencedFromSourceString = new Box<>();
-    referencedFrom[0].getReference(
-        classReference -> referencedFromSourceString.set(classReference.getTypeName()),
-        fieldReference ->
-            referencedFromSourceString.set(FieldReferenceUtils.toSourceString(fieldReference)),
-        methodReference ->
-            referencedFromSourceString.set(MethodReferenceUtils.toSourceString(methodReference)));
     inspectDiagnosticsWithNoRules(
         diagnostics,
         referencedFrom,
-        getExpectedDiagnosticMessage(referencedFromSourceString.get(), referencedFrom.length));
+        getExpectedDiagnosticMessage(
+            MissingDefinitionContextUtils.toSourceString(referencedFrom[0]),
+            referencedFrom.length));
   }
 
   void inspectDiagnosticsWithNoRules(