Introduce MultiAPI level HumanToMachine converter

Bug: b/222647019
Change-Id: I8ea0c2a488b330079384e9ace7ccc22cbd19a4c8
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/ApiLevelRange.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/ApiLevelRange.java
index 66a980a..e13fb7c 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/ApiLevelRange.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/ApiLevelRange.java
@@ -50,7 +50,7 @@
     }
     ApiLevelRange that = (ApiLevelRange) o;
     return apiLevelBelowOrEqual.equals(that.apiLevelBelowOrEqual)
-        && apiLevelGreaterOrEqual.equals(that.apiLevelGreaterOrEqual);
+        && Objects.equals(apiLevelGreaterOrEqual, that.apiLevelGreaterOrEqual);
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MultiAPILevelMachineDesugaredLibrarySpecification.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MultiAPILevelMachineDesugaredLibrarySpecification.java
new file mode 100644
index 0000000..04ddb16
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MultiAPILevelMachineDesugaredLibrarySpecification.java
@@ -0,0 +1,51 @@
+// Copyright (c) 2022, 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.machinespecification;
+
+import com.android.tools.r8.ir.desugar.desugaredlibrary.ApiLevelRange;
+import com.android.tools.r8.origin.Origin;
+import java.util.Map;
+
+public class MultiAPILevelMachineDesugaredLibrarySpecification {
+
+  private final Origin origin;
+  private final MachineTopLevelFlags topLevelFlags;
+  private final Map<ApiLevelRange, MachineRewritingFlags> commonFlags;
+  private final Map<ApiLevelRange, MachineRewritingFlags> libraryFlags;
+  private final Map<ApiLevelRange, MachineRewritingFlags> programFlags;
+
+  public MultiAPILevelMachineDesugaredLibrarySpecification(
+      Origin origin,
+      MachineTopLevelFlags topLevelFlags,
+      Map<ApiLevelRange, MachineRewritingFlags> commonFlags,
+      Map<ApiLevelRange, MachineRewritingFlags> libraryFlags,
+      Map<ApiLevelRange, MachineRewritingFlags> programFlags) {
+    this.origin = origin;
+    this.topLevelFlags = topLevelFlags;
+    this.commonFlags = commonFlags;
+    this.libraryFlags = libraryFlags;
+    this.programFlags = programFlags;
+  }
+
+  public Origin getOrigin() {
+    return origin;
+  }
+
+  public MachineTopLevelFlags getTopLevelFlags() {
+    return topLevelFlags;
+  }
+
+  public Map<ApiLevelRange, MachineRewritingFlags> getCommonFlags() {
+    return commonFlags;
+  }
+
+  public Map<ApiLevelRange, MachineRewritingFlags> getLibraryFlags() {
+    return libraryFlags;
+  }
+
+  public Map<ApiLevelRange, MachineRewritingFlags> getProgramFlags() {
+    return programFlags;
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachinePrefixConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachinePrefixConverter.java
index 473cfda..51262ef 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachinePrefixConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachinePrefixConverter.java
@@ -8,7 +8,6 @@
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanRewritingFlags;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineRewritingFlags;
 import com.android.tools.r8.utils.DescriptorUtils;
@@ -34,12 +33,13 @@
   public HumanToMachinePrefixConverter(
       AppInfoWithClassHierarchy appInfo,
       MachineRewritingFlags.Builder builder,
-      HumanDesugaredLibrarySpecification humanSpec,
+      String synthesizedPrefix,
+      boolean libraryCompilation,
       HumanRewritingFlags rewritingFlags) {
     this.appInfo = appInfo;
     this.builder = builder;
-    this.synthesizedPrefix = humanSpec.getSynthesizedLibraryClassesPackagePrefix();
-    this.libraryCompilation = humanSpec.isLibraryCompilation();
+    this.synthesizedPrefix = synthesizedPrefix;
+    this.libraryCompilation = libraryCompilation;
     this.descriptorPrefix = convertRewritePrefix(rewritingFlags.getRewritePrefix());
     this.descriptorDontRewritePrefix = convertPrefixSet(rewritingFlags.getDontRewritePrefix());
     this.descriptorMaintainPrefix = convertPrefixSet(rewritingFlags.getMaintainPrefix());
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java
index 0797395..eb333a7 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java
@@ -13,20 +13,26 @@
 import com.android.tools.r8.graph.DexReference;
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.ApiLevelRange;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibraryAmender;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanRewritingFlags;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanTopLevelFlags;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.MultiAPILevelHumanDesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.CustomConversionDescriptor;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineDesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineRewritingFlags;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineTopLevelFlags;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MultiAPILevelMachineDesugaredLibrarySpecification;
 import com.android.tools.r8.synthesis.SyntheticItems.GlobalSyntheticsStrategy;
 import com.android.tools.r8.utils.Reporter;
 import com.android.tools.r8.utils.Timing;
 import com.google.common.collect.Sets;
+import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 public class HumanToMachineSpecificationConverter {
@@ -40,6 +46,44 @@
     this.timing = timing;
   }
 
+  public MultiAPILevelMachineDesugaredLibrarySpecification convertAllAPILevels(
+      MultiAPILevelHumanDesugaredLibrarySpecification humanSpec, DexApplication app)
+      throws IOException {
+    timing.begin("Legacy to human all API convert");
+    reporter = app.options.reporter;
+    appInfo =
+        AppInfoWithClassHierarchy.createForDesugaring(
+            AppInfo.createInitialAppInfo(app, GlobalSyntheticsStrategy.forNonSynthesizing()));
+
+    MachineTopLevelFlags machineTopLevelFlags = convertTopLevelFlags(humanSpec.getTopLevelFlags());
+    String synthesizedPrefix = machineTopLevelFlags.getSynthesizedLibraryClassesPackagePrefix();
+    Map<ApiLevelRange, MachineRewritingFlags> commonFlags =
+        convertRewritingFlagMap(humanSpec.getCommonFlags(), synthesizedPrefix, true);
+    Map<ApiLevelRange, MachineRewritingFlags> programFlags =
+        convertRewritingFlagMap(humanSpec.getProgramFlags(), synthesizedPrefix, false);
+    Map<ApiLevelRange, MachineRewritingFlags> libraryFlags =
+        convertRewritingFlagMap(humanSpec.getLibraryFlags(), synthesizedPrefix, true);
+
+    MultiAPILevelMachineDesugaredLibrarySpecification machineSpec =
+        new MultiAPILevelMachineDesugaredLibrarySpecification(
+            humanSpec.getOrigin(), machineTopLevelFlags, commonFlags, libraryFlags, programFlags);
+    timing.end();
+    return machineSpec;
+  }
+
+  private Map<ApiLevelRange, MachineRewritingFlags> convertRewritingFlagMap(
+      Map<ApiLevelRange, HumanRewritingFlags> libFlags,
+      String synthesizedPrefix,
+      boolean interpretAsLibraryCompilation) {
+    Map<ApiLevelRange, MachineRewritingFlags> map = new HashMap<>();
+    libFlags.forEach(
+        (range, flags) ->
+            map.put(
+                range,
+                convertRewritingFlags(flags, synthesizedPrefix, interpretAsLibraryCompilation)));
+    return map;
+  }
+
   public MachineDesugaredLibrarySpecification convert(
       HumanDesugaredLibrarySpecification humanSpec, DexApplication app) {
     timing.begin("Human to machine convert");
@@ -51,7 +95,11 @@
         app,
         humanSpec.isLibraryCompilation(),
         humanSpec.getTopLevelFlags().getRequiredCompilationAPILevel());
-    MachineRewritingFlags machineRewritingFlags = convertRewritingFlags(humanSpec);
+    MachineRewritingFlags machineRewritingFlags =
+        convertRewritingFlags(
+            humanSpec.getRewritingFlags(),
+            humanSpec.getSynthesizedLibraryClassesPackagePrefix(),
+            humanSpec.isLibraryCompilation());
     MachineTopLevelFlags topLevelFlags = convertTopLevelFlags(humanSpec.getTopLevelFlags());
     timing.end();
     return new MachineDesugaredLibrarySpecification(
@@ -69,9 +117,8 @@
   }
 
   private MachineRewritingFlags convertRewritingFlags(
-      HumanDesugaredLibrarySpecification humanSpec) {
+      HumanRewritingFlags rewritingFlags, String synthesizedPrefix, boolean libraryCompilation) {
     timing.begin("convert rewriting flags");
-    HumanRewritingFlags rewritingFlags = humanSpec.getRewritingFlags();
     MachineRewritingFlags.Builder builder = MachineRewritingFlags.builder();
     DesugaredLibraryAmender.run(
         rewritingFlags.getAmendLibraryMethod(),
@@ -86,7 +133,8 @@
         .convertRetargetFlags(rewritingFlags, builder, this::warnMissingReferences);
     new HumanToMachineEmulatedInterfaceConverter(appInfo)
         .convertEmulatedInterfaces(rewritingFlags, appInfo, builder, this::warnMissingReferences);
-    new HumanToMachinePrefixConverter(appInfo, builder, humanSpec, rewritingFlags)
+    new HumanToMachinePrefixConverter(
+            appInfo, builder, synthesizedPrefix, libraryCompilation, rewritingFlags)
         .convertPrefixFlags(rewritingFlags, this::warnMissingDexString);
     new HumanToMachineWrapperConverter(appInfo)
         .convertWrappers(rewritingFlags, builder, this::warnMissingReferences);
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/specification/ConvertExportReadTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/specification/ConvertExportReadTest.java
index cd43698..8946a8e 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/specification/ConvertExportReadTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/specification/ConvertExportReadTest.java
@@ -22,6 +22,8 @@
 import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.MultiAPILevelHumanDesugaredLibrarySpecificationParser;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.legacyspecification.MultiAPILevelLegacyDesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.legacyspecification.MultiAPILevelLegacyDesugaredLibrarySpecificationParser;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MultiAPILevelMachineDesugaredLibrarySpecification;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.specificationconversion.HumanToMachineSpecificationConverter;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.specificationconversion.LegacyToHumanSpecificationConverter;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.utils.Box;
@@ -76,6 +78,12 @@
             .parseMultiLevelConfiguration(StringResource.fromString(json.get(), Origin.unknown()));
 
     assertSpecEquals(humanSpec1, humanSpec2);
+
+    HumanToMachineSpecificationConverter converter2 =
+        new HumanToMachineSpecificationConverter(Timing.empty());
+    MultiAPILevelMachineDesugaredLibrarySpecification machineSpec1 =
+        converter2.convertAllAPILevels(humanSpec2, app);
+    System.out.println("x");
   }
 
   private void assertSpecEquals(