[ApiModel] Rewrite outline desugaring to use DesugarDescription

Change-Id: Ib5aa742097850324b2b4266633957cccf10b10c8
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaring.java
index 810812a..8f1ddeb 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaring.java
@@ -6,6 +6,7 @@
 
 import com.android.tools.r8.cf.code.CfInstruction;
 import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
+import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.ProgramMethod;
 import java.util.Collection;
@@ -33,7 +34,7 @@
    * Given an instruction, returns the list of instructions that the instruction should be desugared
    * to. If no desugaring is needed, {@code null} should be returned (for efficiency).
    */
-  Collection<CfInstruction> desugarInstruction(
+  default Collection<CfInstruction> desugarInstruction(
       CfInstruction instruction,
       FreshLocalProvider freshLocalProvider,
       LocalStackAllocator localStackAllocator,
@@ -41,14 +42,25 @@
       ProgramMethod context,
       MethodProcessingContext methodProcessingContext,
       CfInstructionDesugaringCollection desugaringCollection,
-      DexItemFactory dexItemFactory);
+      DexItemFactory dexItemFactory) {
+    return compute(instruction, context)
+        .desugarInstruction(
+            freshLocalProvider,
+            localStackAllocator,
+            eventConsumer,
+            context,
+            methodProcessingContext,
+            dexItemFactory);
+  }
 
   /**
    * Returns true if the given instruction needs desugaring.
    *
    * <p>This should return true if-and-only-if {@link #desugarInstruction} returns non-null.
    */
-  boolean needsDesugaring(CfInstruction instruction, ProgramMethod context);
+  default boolean needsDesugaring(CfInstruction instruction, ProgramMethod context) {
+    return compute(instruction, context).needsDesugaring();
+  }
 
   /**
    * Returns true if and only if needsDesugaring() answering true implies a desugaring is needed.
@@ -59,4 +71,8 @@
   default boolean hasPreciseNeedsDesugaring() {
     return true;
   }
+
+  default DesugarDescription compute(CfInstruction instruction, ProgramMethod context) {
+    throw new Unreachable();
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/apimodel/ApiInvokeOutlinerDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/apimodel/ApiInvokeOutlinerDesugaring.java
index 99eef8c..292d844 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/apimodel/ApiInvokeOutlinerDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/apimodel/ApiInvokeOutlinerDesugaring.java
@@ -14,7 +14,6 @@
 import com.android.tools.r8.cf.code.CfInstanceOf;
 import com.android.tools.r8.cf.code.CfInstruction;
 import com.android.tools.r8.cf.code.CfInvoke;
-import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
 import com.android.tools.r8.contexts.CompilationContext.UniqueContext;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexClass;
@@ -31,10 +30,7 @@
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.desugar.CfInstructionDesugaring;
-import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection;
-import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.FreshLocalProvider;
-import com.android.tools.r8.ir.desugar.LocalStackAllocator;
+import com.android.tools.r8.ir.desugar.DesugarDescription;
 import com.android.tools.r8.ir.synthetic.CheckCastSourceCode;
 import com.android.tools.r8.ir.synthetic.ConstClassSourceCode;
 import com.android.tools.r8.ir.synthetic.FieldAccessorBuilder;
@@ -69,33 +65,28 @@
   }
 
   @Override
-  public Collection<CfInstruction> desugarInstruction(
-      CfInstruction instruction,
-      FreshLocalProvider freshLocalProvider,
-      LocalStackAllocator localStackAllocator,
-      CfInstructionDesugaringEventConsumer eventConsumer,
-      ProgramMethod context,
-      MethodProcessingContext methodProcessingContext,
-      CfInstructionDesugaringCollection desugaringCollection,
-      DexItemFactory dexItemFactory) {
+  public DesugarDescription compute(CfInstruction instruction, ProgramMethod context) {
     ComputedApiLevel computedApiLevel =
         getComputedApiLevelInstructionOnHolderWithMinApi(instruction, context);
-    if (computedApiLevel.isGreaterThan(appView.computedMinApiLevel())) {
-      return desugarLibraryCall(
-          methodProcessingContext.createUniqueContext(),
-          instruction,
-          computedApiLevel,
-          dexItemFactory,
-          eventConsumer,
-          context);
+    if (appView.computedMinApiLevel().isGreaterThanOrEqualTo(computedApiLevel)) {
+      return DesugarDescription.nothing();
     }
-    return null;
-  }
-
-  @Override
-  public boolean needsDesugaring(CfInstruction instruction, ProgramMethod context) {
-    return getComputedApiLevelInstructionOnHolderWithMinApi(instruction, context)
-        .isGreaterThan(appView.computedMinApiLevel());
+    return DesugarDescription.builder()
+        .setDesugarRewrite(
+            (freshLocalProvider,
+                localStackAllocator,
+                eventConsumer,
+                context1,
+                methodProcessingContext,
+                dexItemFactory) ->
+                desugarLibraryCall(
+                    methodProcessingContext.createUniqueContext(),
+                    instruction,
+                    computedApiLevel,
+                    dexItemFactory,
+                    eventConsumer,
+                    context))
+        .build();
   }
 
   private ComputedApiLevel getComputedApiLevelInstructionOnHolderWithMinApi(