DesugaredLibraryRetargeter l8 synthesis moved upfront

Bug:191656218
Change-Id: Id4b87e29b8c9e87740d38c6d3d9acf4d98ce31c8
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
index c8ce45d..2a30a23 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/ClassConverter.java
@@ -13,7 +13,6 @@
 import com.android.tools.r8.ir.desugar.CfClassDesugaringEventConsumer.D8CfClassDesugaringEventConsumer;
 import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
 import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer.D8CfInstructionDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.CfL8ClassSynthesizerCollection;
 import com.android.tools.r8.ir.desugar.CfL8ClassSynthesizerEventConsumer;
 import com.android.tools.r8.utils.ThreadUtils;
 import com.google.common.collect.ImmutableList;
@@ -59,8 +58,7 @@
     if (appView.options().isDesugaredLibraryCompilation()) {
       CfL8ClassSynthesizerEventConsumer l8ClassSynthesizerEventConsumer =
           new CfL8ClassSynthesizerEventConsumer();
-      new CfL8ClassSynthesizerCollection(appView)
-          .synthesizeClasses(executorService, l8ClassSynthesizerEventConsumer);
+      converter.l8ClassSynthesis(executorService, l8ClassSynthesizerEventConsumer);
       classes =
           ImmutableList.<DexProgramClass>builder()
               .addAll(classes)
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index 4c76828..c2572cf 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -49,6 +49,8 @@
 import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection;
 import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
 import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer.D8CfInstructionDesugaringEventConsumer;
+import com.android.tools.r8.ir.desugar.CfL8ClassSynthesizerCollection;
+import com.android.tools.r8.ir.desugar.CfL8ClassSynthesizerEventConsumer;
 import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringCollection;
 import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer;
 import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer.D8CfPostProcessingDesugaringEventConsumer;
@@ -442,6 +444,14 @@
     return application;
   }
 
+  public void l8ClassSynthesis(
+      ExecutorService executorService,
+      CfL8ClassSynthesizerEventConsumer l8ClassSynthesizerEventConsumer)
+      throws ExecutionException {
+    new CfL8ClassSynthesizerCollection(appView, instructionDesugaring.getRetargetingInfo())
+        .synthesizeClasses(executorService, l8ClassSynthesizerEventConsumer);
+  }
+
   private void postProcessingDesugaringForD8(
       D8MethodProcessor methodProcessor, ExecutorService executorService)
       throws ExecutionException {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
index abc61f9..6eda99c 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringEventConsumer.java
@@ -14,7 +14,7 @@
 import com.android.tools.r8.ir.conversion.ClassConverterResult;
 import com.android.tools.r8.ir.conversion.D8MethodProcessor;
 import com.android.tools.r8.ir.desugar.backports.BackportedMethodDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeterInstructionEventConsumer;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeterSynthesizerEventConsumer.DesugaredLibraryRetargeterInstructionEventConsumer;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryWrapperSynthesizerEventConsumer.DesugaredLibraryAPIConverterEventConsumer;
 import com.android.tools.r8.ir.desugar.invokespecial.InvokeSpecialBridgeInfo;
 import com.android.tools.r8.ir.desugar.invokespecial.InvokeSpecialToSelfDesugaringEventConsumer;
@@ -79,11 +79,6 @@
       }
 
       @Override
-      public void acceptDesugaredLibraryRetargeterDispatchProgramClass(DexProgramClass clazz) {
-        assert false;
-      }
-
-      @Override
       public void acceptDesugaredLibraryRetargeterDispatchClasspathClass(DexClasspathClass clazz) {
         assert false;
       }
@@ -165,11 +160,6 @@
     }
 
     @Override
-    public void acceptDesugaredLibraryRetargeterDispatchProgramClass(DexProgramClass clazz) {
-      methodProcessor.scheduleDesugaredMethodsForProcessing(clazz.programMethods());
-    }
-
-    @Override
     public void acceptDesugaredLibraryRetargeterDispatchClasspathClass(DexClasspathClass clazz) {
       // Intentionally empty.
     }
@@ -331,12 +321,6 @@
     }
 
     @Override
-    public void acceptDesugaredLibraryRetargeterDispatchProgramClass(DexProgramClass clazz) {
-      // Called only in Desugared library compilation which is D8.
-      assert false;
-    }
-
-    @Override
     public void acceptDesugaredLibraryRetargeterDispatchClasspathClass(DexClasspathClass clazz) {
       additions.addLiveClasspathClass(clazz);
     }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfL8ClassSynthesizerCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/CfL8ClassSynthesizerCollection.java
index 9658586..69a0ebe 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfL8ClassSynthesizerCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfL8ClassSynthesizerCollection.java
@@ -5,7 +5,9 @@
 package com.android.tools.r8.ir.desugar;
 
 import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeterL8Synthesizer;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryWrapperSynthesizer;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.RetargetingInfo;
 import com.android.tools.r8.ir.desugar.itf.EmulatedInterfaceSynthesizer;
 import com.android.tools.r8.utils.ThreadUtils;
 import java.util.ArrayList;
@@ -18,13 +20,18 @@
 
   private Collection<CfL8ClassSynthesizer> synthesizers = new ArrayList<>();
 
-  public CfL8ClassSynthesizerCollection(AppView<?> appView) {
+  public CfL8ClassSynthesizerCollection(AppView<?> appView, RetargetingInfo retargetingInfo) {
     assert appView.options().isDesugaredLibraryCompilation();
     EmulatedInterfaceSynthesizer emulatedInterfaceSynthesizer =
         EmulatedInterfaceSynthesizer.create(appView);
     if (emulatedInterfaceSynthesizer != null) {
       synthesizers.add(emulatedInterfaceSynthesizer);
     }
+    DesugaredLibraryRetargeterL8Synthesizer retargeterL8Synthesizer =
+        DesugaredLibraryRetargeterL8Synthesizer.create(appView, retargetingInfo);
+    if (retargeterL8Synthesizer != null) {
+      synthesizers.add(retargeterL8Synthesizer);
+    }
     synthesizers.add(new DesugaredLibraryWrapperSynthesizer(appView));
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfL8ClassSynthesizerEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfL8ClassSynthesizerEventConsumer.java
index 6687e57..5e41810 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfL8ClassSynthesizerEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfL8ClassSynthesizerEventConsumer.java
@@ -5,6 +5,7 @@
 package com.android.tools.r8.ir.desugar;
 
 import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeterSynthesizerEventConsumer.DesugaredLibraryRetargeterL8SynthesizerEventConsumer;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryWrapperSynthesizerEventConsumer.DesugaredLibraryL8ProgramWrapperSynthesizerEventConsumer;
 import com.android.tools.r8.ir.desugar.itf.EmulatedInterfaceSynthesizerEventConsumer;
 import com.google.common.collect.Sets;
@@ -12,7 +13,8 @@
 
 public class CfL8ClassSynthesizerEventConsumer
     implements EmulatedInterfaceSynthesizerEventConsumer,
-        DesugaredLibraryL8ProgramWrapperSynthesizerEventConsumer {
+        DesugaredLibraryL8ProgramWrapperSynthesizerEventConsumer,
+        DesugaredLibraryRetargeterL8SynthesizerEventConsumer {
 
   private Set<DexProgramClass> synthesizedClasses = Sets.newConcurrentHashSet();
 
@@ -26,6 +28,11 @@
     synthesizedClasses.add(clazz);
   }
 
+  @Override
+  public void acceptDesugaredLibraryRetargeterDispatchProgramClass(DexProgramClass clazz) {
+    synthesizedClasses.add(clazz);
+  }
+
   public Set<DexProgramClass> getSynthesizedClasses() {
     return synthesizedClasses;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringCollection.java
index e539861..2d99720 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringCollection.java
@@ -53,7 +53,8 @@
         InterfaceMethodProcessorFacade interfaceMethodProcessorFacade,
         RetargetingInfo retargetingInfo) {
       ArrayList<CfPostProcessingDesugaring> desugarings = new ArrayList<>();
-      if (!appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember().isEmpty()) {
+      if (!appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember().isEmpty()
+          && !appView.options().isDesugaredLibraryCompilation()) {
         desugarings.add(new DesugaredLibraryRetargeterPostProcessor(appView, retargetingInfo));
       }
       if (interfaceMethodProcessorFacade != null) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java
index 796c01b..e7f6122 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfPostProcessingDesugaringEventConsumer.java
@@ -3,13 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.ir.desugar;
 
-import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexClasspathClass;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.conversion.D8MethodProcessor;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeterInstructionEventConsumer.DesugaredLibraryRetargeterPostProcessingEventConsumer;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeterSynthesizerEventConsumer.DesugaredLibraryRetargeterPostProcessingEventConsumer;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryWrapperSynthesizerEventConsumer.DesugaredLibraryAPICallbackSynthesizorEventConsumer;
 import com.android.tools.r8.ir.desugar.itf.InterfaceProcessingDesugaringEventConsumer;
 import com.android.tools.r8.shaking.Enqueuer.SyntheticAdditions;
@@ -50,11 +49,6 @@
     }
 
     @Override
-    public void acceptDesugaredLibraryRetargeterDispatchProgramClass(DexProgramClass clazz) {
-      methodsToReprocess.addAll(clazz.programMethods());
-    }
-
-    @Override
     public void acceptDesugaredLibraryRetargeterDispatchClasspathClass(DexClasspathClass clazz) {
       // Intentionally empty.
     }
@@ -103,12 +97,6 @@
     }
 
     @Override
-    public void acceptDesugaredLibraryRetargeterDispatchProgramClass(DexProgramClass clazz) {
-      // TODO(b/191656218): Remove unneeded method.
-      throw new Unreachable();
-    }
-
-    @Override
     public void acceptInterfaceInjection(DexProgramClass clazz, DexClass newInterface) {
       additions.injectInterface(clazz, newInterface);
     }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeter.java
index a4c9b12..94d1ce7 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeter.java
@@ -124,7 +124,7 @@
         new InvokeRetargetingResult(false, ignored -> null);
 
     private final boolean hasNewInvokeTarget;
-    private final Function<DesugaredLibraryRetargeterInstructionEventConsumer, DexMethod>
+    private final Function<DesugaredLibraryRetargeterSynthesizerEventConsumer, DexMethod>
         newInvokeTargetSupplier;
 
     static InvokeRetargetingResult createInvokeRetargetingResult(DexMethod retarget) {
@@ -136,7 +136,7 @@
 
     private InvokeRetargetingResult(
         boolean hasNewInvokeTarget,
-        Function<DesugaredLibraryRetargeterInstructionEventConsumer, DexMethod>
+        Function<DesugaredLibraryRetargeterSynthesizerEventConsumer, DexMethod>
             newInvokeTargetSupplier) {
       this.hasNewInvokeTarget = hasNewInvokeTarget;
       this.newInvokeTargetSupplier = newInvokeTargetSupplier;
@@ -147,7 +147,7 @@
     }
 
     public DexMethod getNewInvokeTarget(
-        DesugaredLibraryRetargeterInstructionEventConsumer eventConsumer) {
+        DesugaredLibraryRetargeterSynthesizerEventConsumer eventConsumer) {
       assert hasNewInvokeTarget();
       return newInvokeTargetSupplier.apply(eventConsumer);
     }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterInstructionEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterInstructionEventConsumer.java
deleted file mode 100644
index ed29d61..0000000
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterInstructionEventConsumer.java
+++ /dev/null
@@ -1,25 +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.ir.desugar.desugaredlibrary;
-
-import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexClasspathClass;
-import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.ProgramMethod;
-
-public interface DesugaredLibraryRetargeterInstructionEventConsumer {
-
-  void acceptDesugaredLibraryRetargeterDispatchProgramClass(DexProgramClass clazz);
-
-  void acceptDesugaredLibraryRetargeterDispatchClasspathClass(DexClasspathClass clazz);
-
-  interface DesugaredLibraryRetargeterPostProcessingEventConsumer
-      extends DesugaredLibraryRetargeterInstructionEventConsumer {
-
-    void acceptInterfaceInjection(DexProgramClass clazz, DexClass newInterface);
-
-    void acceptForwardingMethod(ProgramMethod method);
-  }
-}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterL8Synthesizer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterL8Synthesizer.java
new file mode 100644
index 0000000..4d43106
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterL8Synthesizer.java
@@ -0,0 +1,55 @@
+// 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.ir.desugar.desugaredlibrary;
+
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.ir.desugar.CfL8ClassSynthesizer;
+import com.android.tools.r8.ir.desugar.CfL8ClassSynthesizerEventConsumer;
+import com.android.tools.r8.utils.collections.DexClassAndMethodSet;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
+public class DesugaredLibraryRetargeterL8Synthesizer implements CfL8ClassSynthesizer {
+
+  private final AppView<?> appView;
+  private final DesugaredLibraryRetargeterSyntheticHelper syntheticHelper;
+  private final DexClassAndMethodSet emulatedDispatchMethods;
+
+  public static DesugaredLibraryRetargeterL8Synthesizer create(
+      AppView<?> appView, RetargetingInfo retargetingInfo) {
+    assert appView.options().isDesugaredLibraryCompilation();
+    if (retargetingInfo == null || retargetingInfo.getEmulatedDispatchMethods().isEmpty()) {
+      assert appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember().isEmpty();
+      return null;
+    }
+    return new DesugaredLibraryRetargeterL8Synthesizer(appView, retargetingInfo);
+  }
+
+  public DesugaredLibraryRetargeterL8Synthesizer(
+      AppView<?> appView, RetargetingInfo retargetingInfo) {
+    this.appView = appView;
+    this.syntheticHelper = new DesugaredLibraryRetargeterSyntheticHelper(appView);
+    emulatedDispatchMethods = retargetingInfo.getEmulatedDispatchMethods();
+  }
+
+  @Override
+  public List<Future<?>> synthesizeClasses(
+      ExecutorService executorService, CfL8ClassSynthesizerEventConsumer eventConsumer) {
+    assert !emulatedDispatchMethods.isEmpty();
+    List<Future<?>> futures = new ArrayList<>();
+    for (DexClassAndMethod emulatedDispatchMethod : emulatedDispatchMethods) {
+      futures.add(
+          executorService.submit(
+              () -> {
+                syntheticHelper.ensureEmulatedHolderDispatchMethod(
+                    emulatedDispatchMethod, eventConsumer);
+                return null;
+              }));
+    }
+    return futures;
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterPostProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterPostProcessor.java
index 64d3cc6..b6200cb 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterPostProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterPostProcessor.java
@@ -15,7 +15,7 @@
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaring;
 import com.android.tools.r8.ir.desugar.CfPostProcessingDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeterInstructionEventConsumer.DesugaredLibraryRetargeterPostProcessingEventConsumer;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeterSynthesizerEventConsumer.DesugaredLibraryRetargeterPostProcessingEventConsumer;
 import com.android.tools.r8.utils.OptionalBool;
 import com.android.tools.r8.utils.collections.DexClassAndMethodSet;
 import com.google.common.collect.Maps;
@@ -49,11 +49,8 @@
       CfPostProcessingDesugaringEventConsumer eventConsumer,
       ExecutorService executorService)
       throws ExecutionException {
-    if (appView.options().isDesugaredLibraryCompilation()) {
-      ensureEmulatedDispatchMethodsSynthesized(eventConsumer);
-    } else {
-      ensureInterfacesAndForwardingMethodsSynthesized(programClasses, eventConsumer);
-    }
+    assert !appView.options().isDesugaredLibraryCompilation();
+    ensureInterfacesAndForwardingMethodsSynthesized(programClasses, eventConsumer);
   }
 
   private void ensureInterfacesAndForwardingMethodsSynthesized(
@@ -150,17 +147,6 @@
     return desugaringForwardingMethod;
   }
 
-  private void ensureEmulatedDispatchMethodsSynthesized(
-      DesugaredLibraryRetargeterInstructionEventConsumer eventConsumer) {
-    assert appView.options().isDesugaredLibraryCompilation();
-    if (emulatedDispatchMethods.isEmpty()) {
-      return;
-    }
-    for (DexClassAndMethod emulatedDispatchMethod : emulatedDispatchMethods) {
-      syntheticHelper.ensureEmulatedHolderDispatchMethod(emulatedDispatchMethod, eventConsumer);
-    }
-  }
-
   private void reportInvalidLibrarySupertype(
       DexLibraryClass libraryClass, DexClassAndMethodSet retarget) {
     DexClass dexClass = appView.definitionFor(libraryClass.superType);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterSynthesizerEventConsumer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterSynthesizerEventConsumer.java
new file mode 100644
index 0000000..81b65dc
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterSynthesizerEventConsumer.java
@@ -0,0 +1,53 @@
+// 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.ir.desugar.desugaredlibrary;
+
+import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClasspathClass;
+import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.ProgramMethod;
+
+public interface DesugaredLibraryRetargeterSynthesizerEventConsumer {
+
+  default DesugaredLibraryRetargeterL8SynthesizerEventConsumer asProgramSynthesizer() {
+    assert false;
+    return null;
+  }
+
+  default DesugaredLibraryRetargeterInstructionEventConsumer asClasspathSynthesizer() {
+    assert false;
+    return null;
+  }
+
+  interface DesugaredLibraryRetargeterL8SynthesizerEventConsumer
+      extends DesugaredLibraryRetargeterSynthesizerEventConsumer {
+
+    @Override
+    default DesugaredLibraryRetargeterL8SynthesizerEventConsumer asProgramSynthesizer() {
+      return this;
+    }
+
+    void acceptDesugaredLibraryRetargeterDispatchProgramClass(DexProgramClass clazz);
+  }
+
+  interface DesugaredLibraryRetargeterInstructionEventConsumer
+      extends DesugaredLibraryRetargeterSynthesizerEventConsumer {
+
+    @Override
+    default DesugaredLibraryRetargeterInstructionEventConsumer asClasspathSynthesizer() {
+      return this;
+    }
+
+    void acceptDesugaredLibraryRetargeterDispatchClasspathClass(DexClasspathClass clazz);
+  }
+
+  interface DesugaredLibraryRetargeterPostProcessingEventConsumer
+      extends DesugaredLibraryRetargeterInstructionEventConsumer {
+
+    void acceptInterfaceInjection(DexProgramClass clazz, DexClass newInterface);
+
+    void acceptForwardingMethod(ProgramMethod method);
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterSyntheticHelper.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterSyntheticHelper.java
index a87f767..35ddc35 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterSyntheticHelper.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryRetargeterSyntheticHelper.java
@@ -11,6 +11,8 @@
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.MethodAccessFlags;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeterSynthesizerEventConsumer.DesugaredLibraryRetargeterInstructionEventConsumer;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryRetargeterSynthesizerEventConsumer.DesugaredLibraryRetargeterL8SynthesizerEventConsumer;
 import com.android.tools.r8.ir.synthetic.EmulateInterfaceSyntheticCfCodeProvider;
 import com.android.tools.r8.synthesis.SyntheticClassBuilder;
 import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
@@ -27,7 +29,7 @@
 
   public DexClass ensureEmulatedHolderDispatchMethod(
       DexClassAndMethod emulatedDispatchMethod,
-      DesugaredLibraryRetargeterInstructionEventConsumer eventConsumer) {
+      DesugaredLibraryRetargeterSynthesizerEventConsumer eventConsumer) {
     assert eventConsumer != null;
     DexClass interfaceClass =
         ensureEmulatedInterfaceDispatchMethod(emulatedDispatchMethod, eventConsumer);
@@ -44,10 +46,19 @@
                   appView,
                   classBuilder ->
                       buildHolderDispatchMethod(classBuilder, emulatedDispatchMethod, itfMethod),
-                  eventConsumer::acceptDesugaredLibraryRetargeterDispatchProgramClass);
+                  clazz -> {
+                    DesugaredLibraryRetargeterL8SynthesizerEventConsumer programEventConsumer =
+                        eventConsumer.asProgramSynthesizer();
+                    assert programEventConsumer != null;
+                    programEventConsumer.acceptDesugaredLibraryRetargeterDispatchProgramClass(
+                        clazz);
+                  });
     } else {
       ClasspathOrLibraryClass context =
           emulatedDispatchMethod.getHolder().asClasspathOrLibraryClass();
+      DesugaredLibraryRetargeterInstructionEventConsumer classpathEventConsumer =
+          eventConsumer.asClasspathSynthesizer();
+      assert classpathEventConsumer != null;
       assert context != null;
       holderDispatch =
           appView
@@ -58,7 +69,7 @@
                   appView,
                   classBuilder ->
                       buildHolderDispatchMethod(classBuilder, emulatedDispatchMethod, itfMethod),
-                  eventConsumer::acceptDesugaredLibraryRetargeterDispatchClasspathClass);
+                  classpathEventConsumer::acceptDesugaredLibraryRetargeterDispatchClasspathClass);
     }
     rewriteType(holderDispatch.type);
     return holderDispatch;
@@ -66,7 +77,7 @@
 
   public DexClass ensureEmulatedInterfaceDispatchMethod(
       DexClassAndMethod emulatedDispatchMethod,
-      DesugaredLibraryRetargeterInstructionEventConsumer eventConsumer) {
+      DesugaredLibraryRetargeterSynthesizerEventConsumer eventConsumer) {
     assert eventConsumer != null;
     DexClass interfaceDispatch;
     if (appView.options().isDesugaredLibraryCompilation()) {
@@ -79,8 +90,17 @@
                   appView,
                   classBuilder ->
                       buildInterfaceDispatchMethod(classBuilder, emulatedDispatchMethod),
-                  eventConsumer::acceptDesugaredLibraryRetargeterDispatchProgramClass);
+                  clazz -> {
+                    DesugaredLibraryRetargeterL8SynthesizerEventConsumer programEventConsumer =
+                        eventConsumer.asProgramSynthesizer();
+                    assert programEventConsumer != null;
+                    programEventConsumer.acceptDesugaredLibraryRetargeterDispatchProgramClass(
+                        clazz);
+                  });
     } else {
+      DesugaredLibraryRetargeterInstructionEventConsumer classpathEventConsumer =
+          eventConsumer.asClasspathSynthesizer();
+      assert classpathEventConsumer != null;
       ClasspathOrLibraryClass context =
           emulatedDispatchMethod.getHolder().asClasspathOrLibraryClass();
       assert context != null;
@@ -93,7 +113,7 @@
                   appView,
                   classBuilder ->
                       buildInterfaceDispatchMethod(classBuilder, emulatedDispatchMethod),
-                  eventConsumer::acceptDesugaredLibraryRetargeterDispatchClasspathClass);
+                  classpathEventConsumer::acceptDesugaredLibraryRetargeterDispatchClasspathClass);
     }
     rewriteType(interfaceDispatch.type);
     return interfaceDispatch;