Revert "Update global synthetics API to support per-file global output."

This reverts commit 3b666fa39bc6420dcbfafcfbc0540be9d4663d20.

Failures on the bots.

Bug: b/230445931
Change-Id: Icce28596d39146314e9385ab883e332014311c3a
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 7cb5133..61aea99 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -185,9 +185,9 @@
             () ->
                 AppInfo.createInitialAppInfo(
                     app,
-                    options.isGeneratingDexIndexed()
-                        ? GlobalSyntheticsStrategy.forSingleOutputMode()
-                        : GlobalSyntheticsStrategy.forPerFileMode(),
+                    options.isGeneratingDexFilePerClassFile()
+                        ? GlobalSyntheticsStrategy.forPerFileMode()
+                        : GlobalSyntheticsStrategy.forSingleOutputMode(),
                     applicationReader.readMainDexClasses(app)));
     return timing.time("Create app-view", () -> AppView.createForD8(appInfo, typeRewriter, timing));
   }
diff --git a/src/main/java/com/android/tools/r8/GlobalSyntheticsConsumer.java b/src/main/java/com/android/tools/r8/GlobalSyntheticsConsumer.java
index 1f982ce..ea8ad11 100644
--- a/src/main/java/com/android/tools/r8/GlobalSyntheticsConsumer.java
+++ b/src/main/java/com/android/tools/r8/GlobalSyntheticsConsumer.java
@@ -3,8 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
-import com.android.tools.r8.references.ClassReference;
-
 /**
  * Consumer receiving the data representing global synthetics for the program.
  *
@@ -27,23 +25,7 @@
    * <p>The encoding of the global synthetics is compiler internal and may vary between compiler
    * versions. The data received here is thus only valid as inputs to the same compiler version.
    *
-   * <p>The context class is the class for which the global synthetic data is needed. If compiling
-   * in DexIndexed mode, the context class will be null.
-   *
-   * <p>The accept method will be called at most once for a given context class (any only once at
-   * all for a DexIndexed mode compilation). The global data for that class may be the same as for
-   * other context classes, but it will be provided for each context.
-   *
-   * @param data Opaque encoding of the global synthetics for the program.
-   * @param context The class giving rise to the global synthetics. Null in DexIndexed mode.
-   * @param handler Diagnostics handler for reporting.
+   * @param bytes Opaque encoding of the global synthetics for the program.
    */
-  void accept(ByteDataView data, ClassReference context, DiagnosticsHandler handler);
-
-  /**
-   * Callback indicating that no more global synthetics will be reported for the compilation unit.
-   *
-   * @param handler Diagnostics handler for reporting.
-   */
-  default void finished(DiagnosticsHandler handler) {}
+  void accept(byte[] bytes);
 }
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
index 0016655..1e62a10 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -52,8 +52,7 @@
 import com.android.tools.r8.utils.Box;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.ExceptionUtils;
-import com.android.tools.r8.utils.InternalGlobalSyntheticsProgramConsumer.InternalGlobalSyntheticsDexIndexedConsumer;
-import com.android.tools.r8.utils.InternalGlobalSyntheticsProgramConsumer.InternalGlobalSyntheticsDexPerFileConsumer;
+import com.android.tools.r8.utils.InternalGlobalSyntheticsProgramConsumer.InternalGlobalSyntheticsDexConsumer;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.OriginalSourceFiles;
 import com.android.tools.r8.utils.PredicateUtils;
@@ -91,7 +90,7 @@
   public Set<VirtualFile> globalSyntheticFiles;
 
   public DexIndexedConsumer programConsumer;
-  public DexFilePerClassFileConsumer globalsSyntheticsConsumer;
+  public InternalGlobalSyntheticsDexConsumer globalsSyntheticsConsumer;
 
   private static class SortAnnotations extends MixedSectionCollection {
 
@@ -222,11 +221,7 @@
       globalSyntheticFiles = new HashSet<>(files);
       virtualFiles.addAll(globalSyntheticFiles);
       globalsSyntheticsConsumer =
-          options.isGeneratingDexFilePerClassFile()
-              ? new InternalGlobalSyntheticsDexPerFileConsumer(
-                  options.getGlobalSyntheticsConsumer(), appView)
-              : new InternalGlobalSyntheticsDexIndexedConsumer(
-                  options.getGlobalSyntheticsConsumer());
+          new InternalGlobalSyntheticsDexConsumer(options.getGlobalSyntheticsConsumer());
     }
     return virtualFiles;
   }
diff --git a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
index d3632ab..7f8d075 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -169,7 +169,7 @@
     }
     if (!globalSyntheticClasses.isEmpty()) {
       InternalGlobalSyntheticsCfConsumer globalsConsumer =
-          new InternalGlobalSyntheticsCfConsumer(options.getGlobalSyntheticsConsumer(), appView);
+          new InternalGlobalSyntheticsCfConsumer(options.getGlobalSyntheticsConsumer());
       for (DexProgramClass clazz : globalSyntheticClasses) {
         writeClassCatchingErrors(
             clazz, globalsConsumer, rewriter, markerString, sourceFileEnvironment);
diff --git a/src/main/java/com/android/tools/r8/utils/InternalGlobalSyntheticsProgramConsumer.java b/src/main/java/com/android/tools/r8/utils/InternalGlobalSyntheticsProgramConsumer.java
index 3be0d57..3945a6e 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalGlobalSyntheticsProgramConsumer.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalGlobalSyntheticsProgramConsumer.java
@@ -12,18 +12,12 @@
 import com.android.tools.r8.GlobalSyntheticsConsumer;
 import com.android.tools.r8.ProgramResource.Kind;
 import com.android.tools.r8.Version;
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.references.Reference;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
-import java.util.IdentityHashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
@@ -32,110 +26,67 @@
   public static final String COMPILER_INFO_ENTRY_NAME = "compilerinfo";
   public static final String OUTPUT_KIND_ENTRY_NAME = "kind";
 
-  // Builder for constructing a valid "globals" data payload.
-  private static class GlobalsFileBuilder {
+  private final GlobalSyntheticsConsumer consumer;
+  private final List<Pair<String, byte[]>> content = new ArrayList<>();
 
-    private final Kind kind;
-    private final List<Pair<String, byte[]>> content = new ArrayList<>();
+  public InternalGlobalSyntheticsProgramConsumer(GlobalSyntheticsConsumer consumer) {
+    this.consumer = consumer;
+  }
 
-    public GlobalsFileBuilder(Kind kind) {
-      this.kind = kind;
+  public abstract Kind getKind();
+
+  synchronized void addGlobalSynthetic(String descriptor, byte[] data) {
+    add(getGlobalSyntheticFileName(descriptor), data);
+  }
+
+  private void add(String entryName, byte[] data) {
+    content.add(new Pair<>(entryName, data));
+  }
+
+  public void finished(DiagnosticsHandler handler) {
+    // Add meta information.
+    add(COMPILER_INFO_ENTRY_NAME, Version.getVersionString().getBytes(StandardCharsets.UTF_8));
+    add(OUTPUT_KIND_ENTRY_NAME, getKind().toString().getBytes(StandardCharsets.UTF_8));
+
+    // Size estimate to avoid reallocation of the byte output array.
+    final int zipHeaderOverhead = 500;
+    final int zipEntryOverhead = 200;
+    int estimatedZipSize =
+        zipHeaderOverhead
+            + ListUtils.fold(
+                content,
+                0,
+                (acc, pair) ->
+                    acc + pair.getFirst().length() + pair.getSecond().length + zipEntryOverhead);
+    ByteArrayOutputStream baos = new ByteArrayOutputStream(estimatedZipSize);
+    try (ZipOutputStream stream = new ZipOutputStream(baos)) {
+      for (Pair<String, byte[]> pair : content) {
+        ZipUtils.writeToZipStream(stream, pair.getFirst(), pair.getSecond(), ZipEntry.STORED);
+        // Clear out the bytes to avoid three copies when converting the boas.
+        pair.setSecond(null);
+      }
+    } catch (IOException e) {
+      handler.error(new ExceptionDiagnostic(e));
+    }
+    byte[] bytes = baos.toByteArray();
+    consumer.accept(bytes);
+  }
+
+  private static String getGlobalSyntheticFileName(String descriptor) {
+    assert descriptor != null && DescriptorUtils.isClassDescriptor(descriptor);
+    return DescriptorUtils.getClassBinaryNameFromDescriptor(descriptor)
+        + GLOBAL_SYNTHETIC_EXTENSION;
+  }
+
+  public static class InternalGlobalSyntheticsDexConsumer
+      extends InternalGlobalSyntheticsProgramConsumer implements DexFilePerClassFileConsumer {
+
+    public InternalGlobalSyntheticsDexConsumer(GlobalSyntheticsConsumer consumer) {
+      super(consumer);
     }
 
+    @Override
     public Kind getKind() {
-      return kind;
-    }
-
-    void addGlobalSynthetic(String descriptor, byte[] data) {
-      add(getGlobalSyntheticFileName(descriptor), data);
-    }
-
-    private void add(String entryName, byte[] data) {
-      content.add(new Pair<>(entryName, data));
-    }
-
-    public byte[] build() throws IOException {
-      // Add meta information.
-      add(COMPILER_INFO_ENTRY_NAME, Version.getVersionString().getBytes(StandardCharsets.UTF_8));
-      add(OUTPUT_KIND_ENTRY_NAME, getKind().toString().getBytes(StandardCharsets.UTF_8));
-
-      // Size estimate to avoid reallocation of the byte output array.
-      final int zipHeaderOverhead = 500;
-      final int zipEntryOverhead = 200;
-      int estimatedZipSize =
-          zipHeaderOverhead
-              + ListUtils.fold(
-                  content,
-                  0,
-                  (acc, pair) ->
-                      acc + pair.getFirst().length() + pair.getSecond().length + zipEntryOverhead);
-      ByteArrayOutputStream baos = new ByteArrayOutputStream(estimatedZipSize);
-      try (ZipOutputStream stream = new ZipOutputStream(baos)) {
-        for (Pair<String, byte[]> pair : content) {
-          ZipUtils.writeToZipStream(stream, pair.getFirst(), pair.getSecond(), ZipEntry.STORED);
-          // Clear out the bytes to avoid three copies when converting the boas.
-          pair.setSecond(null);
-        }
-      }
-      return baos.toByteArray();
-    }
-
-    private static String getGlobalSyntheticFileName(String descriptor) {
-      assert descriptor != null && DescriptorUtils.isClassDescriptor(descriptor);
-      return DescriptorUtils.getClassBinaryNameFromDescriptor(descriptor)
-          + GLOBAL_SYNTHETIC_EXTENSION;
-    }
-  }
-
-  public static class InternalGlobalSyntheticsDexIndexedConsumer
-      implements DexFilePerClassFileConsumer {
-
-    private final GlobalSyntheticsConsumer clientConsumer;
-    private final GlobalsFileBuilder builder = new GlobalsFileBuilder(Kind.DEX);
-
-    public InternalGlobalSyntheticsDexIndexedConsumer(GlobalSyntheticsConsumer clientConsumer) {
-      this.clientConsumer = clientConsumer;
-    }
-
-    @Override
-    public synchronized void accept(
-        String primaryClassDescriptor,
-        ByteDataView data,
-        Set<String> descriptors,
-        DiagnosticsHandler handler) {
-      builder.addGlobalSynthetic(primaryClassDescriptor, data.copyByteData());
-    }
-
-    @Override
-    public void finished(DiagnosticsHandler handler) {
-      byte[] bytes = null;
-      try {
-        bytes = builder.build();
-      } catch (IOException e) {
-        handler.error(new ExceptionDiagnostic(e));
-      }
-      if (bytes != null) {
-        clientConsumer.accept(ByteDataView.of(bytes), null, handler);
-      }
-      clientConsumer.finished(handler);
-    }
-
-    @Override
-    public boolean combineSyntheticClassesWithPrimaryClass() {
-      return false;
-    }
-  }
-
-  public static class InternalGlobalSyntheticsDexPerFileConsumer extends PerFileBase
-      implements DexFilePerClassFileConsumer {
-
-    public InternalGlobalSyntheticsDexPerFileConsumer(
-        GlobalSyntheticsConsumer consumer, AppView appView) {
-      super(consumer, appView);
-    }
-
-    @Override
-    Kind getKind() {
       return Kind.DEX;
     }
 
@@ -145,7 +96,7 @@
         ByteDataView data,
         Set<String> descriptors,
         DiagnosticsHandler handler) {
-      addGlobal(primaryClassDescriptor, data);
+      addGlobalSynthetic(primaryClassDescriptor, data.copyByteData());
     }
 
     @Override
@@ -154,73 +105,21 @@
     }
   }
 
-  public static class InternalGlobalSyntheticsCfConsumer extends PerFileBase
-      implements ClassFileConsumer {
+  public static class InternalGlobalSyntheticsCfConsumer
+      extends InternalGlobalSyntheticsProgramConsumer implements ClassFileConsumer {
 
-    public InternalGlobalSyntheticsCfConsumer(GlobalSyntheticsConsumer consumer, AppView appView) {
-      super(consumer, appView);
+    public InternalGlobalSyntheticsCfConsumer(GlobalSyntheticsConsumer consumer) {
+      super(consumer);
     }
 
     @Override
-    Kind getKind() {
+    public Kind getKind() {
       return Kind.CF;
     }
 
     @Override
     public void accept(ByteDataView data, String descriptor, DiagnosticsHandler handler) {
-      addGlobal(descriptor, data);
-    }
-  }
-
-  private abstract static class PerFileBase {
-
-    private final AppView appView;
-    private final GlobalSyntheticsConsumer clientConsumer;
-    private final Map<DexType, byte[]> globalToBytes = new ConcurrentHashMap<>();
-
-    public PerFileBase(GlobalSyntheticsConsumer consumer, AppView appView) {
-      this.appView = appView;
-      this.clientConsumer = consumer;
-    }
-
-    abstract Kind getKind();
-
-    public void finished(DiagnosticsHandler handler) {
-      Map<DexType, Set<DexType>> contextToGlobals = new IdentityHashMap<>();
-      for (DexType globalType : globalToBytes.keySet()) {
-        for (DexType contextType :
-            appView.getSyntheticItems().getFinalGlobalSyntheticContexts(globalType)) {
-          contextToGlobals
-              .computeIfAbsent(contextType, k -> SetUtils.newIdentityHashSet())
-              .add(globalType);
-        }
-      }
-      contextToGlobals.forEach(
-          (context, globals) -> {
-            GlobalsFileBuilder builder = new GlobalsFileBuilder(getKind());
-            globals.forEach(
-                global ->
-                    builder.addGlobalSynthetic(
-                        global.toDescriptorString(), globalToBytes.get(global)));
-            byte[] bytes = null;
-            try {
-              bytes = builder.build();
-            } catch (IOException e) {
-              handler.error(new ExceptionDiagnostic(e));
-            }
-            if (bytes != null) {
-              clientConsumer.accept(
-                  ByteDataView.of(bytes),
-                  Reference.classFromDescriptor(context.toDescriptorString()),
-                  handler);
-            }
-          });
-      clientConsumer.finished(handler);
-    }
-
-    void addGlobal(String descriptor, ByteDataView data) {
-      DexType type = appView.dexItemFactory().createType(descriptor);
-      globalToBytes.put(type, data.copyByteData());
+      addGlobalSynthetic(descriptor, data.copyByteData());
     }
   }
 }
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassTest.java
index 184e984..b999875 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassTest.java
@@ -7,26 +7,18 @@
 import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForClass;
 import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForDefaultInstanceInitializer;
 import static com.android.tools.r8.apimodel.ApiModelingTestHelper.verifyThat;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeTrue;
 
 import com.android.tools.r8.CompilationMode;
 import com.android.tools.r8.NeverInline;
-import com.android.tools.r8.OutputMode;
 import com.android.tools.r8.SingleTestRunResult;
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestCompilerBuilder;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.references.Reference;
-import com.android.tools.r8.synthesis.globals.GlobalSyntheticsTestingConsumer;
 import com.android.tools.r8.testing.AndroidBuildVersion;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import java.nio.file.Path;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -49,26 +41,18 @@
     return parameters.isDexRuntime() && parameters.getApiLevel().isGreaterThanOrEqualTo(mockLevel);
   }
 
-  private void setupTestCompileBuilder(TestCompilerBuilder<?, ?, ?, ?, ?> testBuilder) {
+  private void setupTestBuilder(TestCompilerBuilder<?, ?, ?, ?, ?> testBuilder) {
     testBuilder
         .addProgramClasses(Main.class, TestClass.class)
         .addLibraryClasses(LibraryClass.class)
         .addDefaultRuntimeLibrary(parameters)
         .setMinApi(parameters.getApiLevel())
+        .addAndroidBuildVersion()
         .apply(ApiModelingTestHelper::enableStubbingOfClasses)
         .apply(setMockApiLevelForClass(LibraryClass.class, mockLevel))
         .apply(setMockApiLevelForDefaultInstanceInitializer(LibraryClass.class, mockLevel));
   }
 
-  private void setupTestRuntimeBuilder(TestCompilerBuilder<?, ?, ?, ?, ?> testBuilder) {
-    testBuilder.setMinApi(parameters.getApiLevel()).addAndroidBuildVersion();
-  }
-
-  private void setupTestBuilder(TestCompilerBuilder<?, ?, ?, ?, ?> testBuilder) {
-    setupTestCompileBuilder(testBuilder);
-    setupTestRuntimeBuilder(testBuilder);
-  }
-
   private boolean addToBootClasspath() {
     return parameters.isDexRuntime()
         && parameters.getRuntime().maxSupportedApiLevel().isGreaterThanOrEqualTo(mockLevel);
@@ -103,63 +87,6 @@
   }
 
   @Test
-  public void testD8MergeIndexed() throws Exception {
-    assumeTrue(parameters.isDexRuntime());
-    testD8Merge(OutputMode.DexIndexed);
-  }
-
-  @Test
-  public void testD8MergeFilePerClass() throws Exception {
-    assumeTrue(parameters.isDexRuntime());
-    testD8Merge(OutputMode.DexFilePerClass);
-  }
-
-  @Test
-  public void testD8MergeFilePerClassFile() throws Exception {
-    assumeTrue(parameters.isDexRuntime());
-    testD8Merge(OutputMode.DexFilePerClassFile);
-  }
-
-  public void testD8Merge(OutputMode outputMode) throws Exception {
-    GlobalSyntheticsTestingConsumer globals = new GlobalSyntheticsTestingConsumer();
-    Path incrementalOut =
-        testForD8()
-            .debug()
-            .setOutputMode(outputMode)
-            .setIntermediate(true)
-            .apply(b -> b.getBuilder().setGlobalSyntheticsConsumer(globals))
-            // TODO(b/213552119): Remove when enabled by default.
-            .apply(ApiModelingTestHelper::enableApiCallerIdentification)
-            .apply(this::setupTestCompileBuilder)
-            .compile()
-            .writeToZip();
-
-    if (isGreaterOrEqualToMockLevel()) {
-      assertFalse(globals.hasGlobals());
-    } else if (outputMode == OutputMode.DexIndexed) {
-      assertTrue(globals.hasGlobals());
-      assertTrue(globals.isSingleGlobal());
-    } else {
-      assertTrue(globals.hasGlobals());
-      // The TestClass does reference the mock and should have globals.
-      assertNotNull(globals.getProvider(Reference.classFromClass(TestClass.class)));
-      // The Main class does not have references to the mock and should have no globals.
-      assertNull(globals.getProvider(Reference.classFromClass(Main.class)));
-    }
-
-    testForD8()
-        .debug()
-        .addProgramFiles(incrementalOut)
-        .apply(b -> b.getBuilder().addGlobalSyntheticsResourceProviders(globals.getProviders()))
-        .apply(this::setupTestRuntimeBuilder)
-        .compile()
-        .applyIf(addToBootClasspath(), b -> b.addBootClasspathClasses(LibraryClass.class))
-        .run(parameters.getRuntime(), Main.class)
-        .apply(this::checkOutput)
-        .inspect(this::inspect);
-  }
-
-  @Test
   public void testR8() throws Exception {
     testForR8(parameters.getBackend())
         .apply(this::setupTestBuilder)
diff --git a/src/test/java/com/android/tools/r8/compilerapi/globalsynthetics/GlobalSyntheticsTest.java b/src/test/java/com/android/tools/r8/compilerapi/globalsynthetics/GlobalSyntheticsTest.java
index e711b40..edc42c2 100644
--- a/src/test/java/com/android/tools/r8/compilerapi/globalsynthetics/GlobalSyntheticsTest.java
+++ b/src/test/java/com/android/tools/r8/compilerapi/globalsynthetics/GlobalSyntheticsTest.java
@@ -3,11 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.compilerapi.globalsynthetics;
 
-import com.android.tools.r8.ByteDataView;
 import com.android.tools.r8.D8;
 import com.android.tools.r8.D8Command;
 import com.android.tools.r8.DexIndexedConsumer;
-import com.android.tools.r8.DiagnosticsHandler;
 import com.android.tools.r8.GlobalSyntheticsConsumer;
 import com.android.tools.r8.GlobalSyntheticsResourceProvider;
 import com.android.tools.r8.ResourceException;
@@ -15,7 +13,6 @@
 import com.android.tools.r8.compilerapi.CompilerApiTest;
 import com.android.tools.r8.compilerapi.CompilerApiTestRunner;
 import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.references.ClassReference;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
@@ -74,16 +71,10 @@
               .setGlobalSyntheticsConsumer(
                   new GlobalSyntheticsConsumer() {
                     @Override
-                    public void accept(
-                        ByteDataView data, ClassReference context, DiagnosticsHandler handler) {
+                    public void accept(byte[] bytes) {
                       // Nothing is actually received here as MockClass does not give rise to
                       // globals.
                     }
-
-                    @Override
-                    public void finished(DiagnosticsHandler handler) {
-                      // Nothing to do, just checking we can override finished.
-                    }
                   })
               .build());
     }
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java
index 596f50f..d3816f8 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordMergeTest.java
@@ -10,7 +10,6 @@
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
 
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.D8TestCompileResult;
@@ -19,7 +18,7 @@
 import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.errors.DuplicateTypesDiagnostic;
 import com.android.tools.r8.errors.MissingGlobalSyntheticsConsumerDiagnostic;
-import com.android.tools.r8.synthesis.globals.GlobalSyntheticsTestingConsumer;
+import com.android.tools.r8.synthesis.globals.GlobalSyntheticsConsumerAndProvider;
 import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import java.nio.file.Path;
@@ -73,10 +72,7 @@
 
   @Test
   public void testMergeDesugaredInputs() throws Exception {
-    // TODO(b/230445931): Records do not yet have contexts so per-file modes fail.
-    //  This test should be extended or duplicated to also test the pre-file-dex modes.
-    assumeTrue("b/230445931", parameters.isDexRuntime());
-    GlobalSyntheticsTestingConsumer globals1 = new GlobalSyntheticsTestingConsumer();
+    GlobalSyntheticsConsumerAndProvider globals1 = new GlobalSyntheticsConsumerAndProvider();
     Path output1 =
         testForD8(parameters.getBackend())
             .addProgramClassFileData(PROGRAM_DATA_1)
@@ -87,7 +83,7 @@
             .inspect(this::assertDoesNotHaveRecordTag)
             .writeToZip();
 
-    GlobalSyntheticsTestingConsumer globals2 = new GlobalSyntheticsTestingConsumer();
+    GlobalSyntheticsConsumerAndProvider globals2 = new GlobalSyntheticsConsumerAndProvider();
     Path output2 =
         testForD8(parameters.getBackend())
             .addProgramClassFileData(PROGRAM_DATA_2)
@@ -98,17 +94,13 @@
             .inspect(this::assertDoesNotHaveRecordTag)
             .writeToZip();
 
-    assertTrue(globals1.hasGlobals());
-    assertTrue(globals2.hasGlobals());
+    assertTrue(globals1.hasBytes());
+    assertTrue(globals2.hasBytes());
 
     D8TestCompileResult result =
         testForD8(parameters.getBackend())
             .addProgramFiles(output1, output2)
-            .apply(
-                b ->
-                    b.getBuilder()
-                        .addGlobalSyntheticsResourceProviders(
-                            globals1.getIndexedModeProvider(), globals2.getIndexedModeProvider()))
+            .apply(b -> b.getBuilder().addGlobalSyntheticsResourceProviders(globals1, globals2))
             .setMinApi(parameters.getApiLevel())
             .compile()
             .inspect(this::assertHasRecordTag);
@@ -119,7 +111,7 @@
 
   @Test
   public void testMergeDesugaredAndNonDesugaredInputs() throws Exception {
-    GlobalSyntheticsTestingConsumer globals1 = new GlobalSyntheticsTestingConsumer();
+    GlobalSyntheticsConsumerAndProvider globals1 = new GlobalSyntheticsConsumerAndProvider();
     Path output1 =
         testForD8(parameters.getBackend())
             .addProgramClassFileData(PROGRAM_DATA_1)
@@ -132,10 +124,7 @@
     D8TestCompileResult result =
         testForD8(parameters.getBackend())
             .addProgramFiles(output1)
-            .apply(
-                b ->
-                    b.getBuilder()
-                        .addGlobalSyntheticsResourceProviders(globals1.getIndexedModeProvider()))
+            .apply(b -> b.getBuilder().addGlobalSyntheticsResourceProviders(globals1))
             .addProgramClassFileData(PROGRAM_DATA_2)
             .setMinApi(parameters.getApiLevel())
             .compile();
diff --git a/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java b/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
index 9a74bb5..e94b6b6 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
@@ -11,7 +11,7 @@
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.synthesis.globals.GlobalSyntheticsTestingConsumer;
+import com.android.tools.r8.synthesis.globals.GlobalSyntheticsConsumerAndProvider;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.StringUtils;
 import java.nio.file.Path;
@@ -75,14 +75,11 @@
   @Test
   public void testD8Intermediate() throws Exception {
     assumeTrue(parameters.isDexRuntime());
-    GlobalSyntheticsTestingConsumer globals = new GlobalSyntheticsTestingConsumer();
+    GlobalSyntheticsConsumerAndProvider globals = new GlobalSyntheticsConsumerAndProvider();
     Path path = compileIntermediate(globals);
     testForD8()
         .addProgramFiles(path)
-        .apply(
-            b ->
-                b.getBuilder()
-                    .addGlobalSyntheticsResourceProviders(globals.getIndexedModeProvider()))
+        .apply(b -> b.getBuilder().addGlobalSyntheticsResourceProviders(globals))
         .setMinApi(parameters.getApiLevel())
         .setIncludeClassesChecksum(true)
         .run(parameters.getRuntime(), MAIN_TYPE)
@@ -92,15 +89,12 @@
   @Test
   public void testD8IntermediateNoDesugaringInStep2() throws Exception {
     assumeTrue(parameters.isDexRuntime());
-    GlobalSyntheticsTestingConsumer globals = new GlobalSyntheticsTestingConsumer();
+    GlobalSyntheticsConsumerAndProvider globals = new GlobalSyntheticsConsumerAndProvider();
     Path path = compileIntermediate(globals);
     // In Android Studio they disable desugaring at this point to improve build speed.
     testForD8()
         .addProgramFiles(path)
-        .apply(
-            b ->
-                b.getBuilder()
-                    .addGlobalSyntheticsResourceProviders(globals.getIndexedModeProvider()))
+        .apply(b -> b.getBuilder().addGlobalSyntheticsResourceProviders(globals))
         .setMinApi(parameters.getApiLevel())
         .setIncludeClassesChecksum(true)
         .disableDesugaring()
diff --git a/src/test/java/com/android/tools/r8/synthesis/globals/GlobalSyntheticsConsumerAndProvider.java b/src/test/java/com/android/tools/r8/synthesis/globals/GlobalSyntheticsConsumerAndProvider.java
new file mode 100644
index 0000000..57f5622
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/synthesis/globals/GlobalSyntheticsConsumerAndProvider.java
@@ -0,0 +1,41 @@
+// 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.synthesis.globals;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import com.android.tools.r8.GlobalSyntheticsConsumer;
+import com.android.tools.r8.GlobalSyntheticsResourceProvider;
+import com.android.tools.r8.ResourceException;
+import com.android.tools.r8.origin.Origin;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+public class GlobalSyntheticsConsumerAndProvider
+    implements GlobalSyntheticsConsumer, GlobalSyntheticsResourceProvider {
+
+  private byte[] bytes;
+
+  @Override
+  public void accept(byte[] bytes) {
+    assertNull(this.bytes);
+    assertNotNull(bytes);
+    this.bytes = bytes;
+  }
+
+  @Override
+  public Origin getOrigin() {
+    return Origin.unknown();
+  }
+
+  @Override
+  public InputStream getByteStream() throws ResourceException {
+    return new ByteArrayInputStream(bytes);
+  }
+
+  public boolean hasBytes() {
+    return true;
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/synthesis/globals/GlobalSyntheticsTestingConsumer.java b/src/test/java/com/android/tools/r8/synthesis/globals/GlobalSyntheticsTestingConsumer.java
deleted file mode 100644
index 51897e6..0000000
--- a/src/test/java/com/android/tools/r8/synthesis/globals/GlobalSyntheticsTestingConsumer.java
+++ /dev/null
@@ -1,96 +0,0 @@
-// 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.synthesis.globals;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import com.android.tools.r8.ByteDataView;
-import com.android.tools.r8.DiagnosticsHandler;
-import com.android.tools.r8.GlobalSyntheticsConsumer;
-import com.android.tools.r8.GlobalSyntheticsResourceProvider;
-import com.android.tools.r8.ResourceException;
-import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.references.ClassReference;
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-public class GlobalSyntheticsTestingConsumer implements GlobalSyntheticsConsumer {
-
-  private final Map<ClassReference, GlobalSyntheticsResourceProvider> globals = new HashMap<>();
-  private boolean finished = false;
-
-  @Override
-  public void accept(ByteDataView data, ClassReference context, DiagnosticsHandler handler) {
-    assertFalse(finished);
-    assertNotNull(data);
-    Origin origin =
-        context == null
-            ? Origin.unknown()
-            : new Origin(Origin.root()) {
-              @Override
-              public String part() {
-                return "globals(" + context.getTypeName() + ")";
-              }
-            };
-    TestingProvider provider = new TestingProvider(origin, data.copyByteData());
-    GlobalSyntheticsResourceProvider old = globals.put(context, provider);
-    assertNull(old);
-  }
-
-  @Override
-  public void finished(DiagnosticsHandler handler) {
-    assertFalse(finished);
-    finished = true;
-  }
-
-  public boolean hasGlobals() {
-    return !globals.isEmpty();
-  }
-
-  public boolean isSingleGlobal() {
-    return globals.size() == 1 && globals.get(null) != null;
-  }
-
-  public GlobalSyntheticsResourceProvider getIndexedModeProvider() {
-    assertTrue(isSingleGlobal());
-    return globals.get(null);
-  }
-
-  public GlobalSyntheticsResourceProvider getProvider(ClassReference clazz) {
-    assertNotNull("Use getIndexedModeProvider to get single outputs", clazz);
-    assertFalse(isSingleGlobal());
-    return globals.get(clazz);
-  }
-
-  public Collection<GlobalSyntheticsResourceProvider> getProviders() {
-    return globals.values();
-  }
-
-  private static class TestingProvider implements GlobalSyntheticsResourceProvider {
-
-    private final Origin origin;
-    private final byte[] bytes;
-
-    public TestingProvider(Origin origin, byte[] bytes) {
-      this.origin = origin;
-      this.bytes = bytes;
-    }
-
-    @Override
-    public Origin getOrigin() {
-      return origin;
-    }
-
-    @Override
-    public InputStream getByteStream() throws ResourceException {
-      return new ByteArrayInputStream(bytes);
-    }
-  }
-}