Remove access to mutable startup profile backing

Bug: b/274723189
Change-Id: I3efe295645d8f0344961a7637dee6febf6ee6b2e
diff --git a/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java b/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java
index e848e3b..c2ae2a1 100644
--- a/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java
+++ b/src/main/java/com/android/tools/r8/dex/StartupMixedSectionLayoutStrategy.java
@@ -8,7 +8,6 @@
 import com.android.tools.r8.experimental.startup.StartupProfile;
 import com.android.tools.r8.experimental.startup.profile.StartupProfileClassRule;
 import com.android.tools.r8.experimental.startup.profile.StartupProfileMethodRule;
-import com.android.tools.r8.experimental.startup.profile.StartupProfileRule;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexAnnotation;
 import com.android.tools.r8.graph.DexAnnotationDirectory;
@@ -82,14 +81,12 @@
             virtualFile.classes().size());
     LensCodeRewriterUtils rewriter = new LensCodeRewriterUtils(appView, true);
     StartupIndexedItemCollection indexedItemCollection = new StartupIndexedItemCollection();
-    for (StartupProfileRule startupItem : startupProfileForWriting.getRules()) {
-      startupItem.accept(
-          startupClass ->
-              collectStartupItems(startupClass, indexedItemCollection, virtualFileDefinitions),
-          startupMethod ->
-              collectStartupItems(
-                  startupMethod, indexedItemCollection, virtualFileDefinitions, rewriter));
-    }
+    startupProfileForWriting.forEachRule(
+        startupClass ->
+            collectStartupItems(startupClass, indexedItemCollection, virtualFileDefinitions),
+        startupMethod ->
+            collectStartupItems(
+                startupMethod, indexedItemCollection, virtualFileDefinitions, rewriter));
   }
 
   private void collectStartupItems(
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/EmptyStartupProfile.java b/src/main/java/com/android/tools/r8/experimental/startup/EmptyStartupProfile.java
index a91c273..f629224 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/EmptyStartupProfile.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/EmptyStartupProfile.java
@@ -14,8 +14,6 @@
 import com.android.tools.r8.graph.PrunedItems;
 import com.android.tools.r8.synthesis.SyntheticItems;
 import com.android.tools.r8.utils.ThrowingConsumer;
-import java.util.Collection;
-import java.util.Collections;
 
 public class EmptyStartupProfile extends StartupProfile {
 
@@ -32,9 +30,15 @@
   }
 
   @Override
+  public <E extends Exception> void forEachRule(
+      ThrowingConsumer<? super StartupProfileRule, E> consumer) {
+    // Intentionally empty.
+  }
+
+  @Override
   public <E1 extends Exception, E2 extends Exception> void forEachRule(
-      ThrowingConsumer<StartupProfileClassRule, E1> classRuleConsumer,
-      ThrowingConsumer<StartupProfileMethodRule, E2> methodRuleConsumer) {
+      ThrowingConsumer<? super StartupProfileClassRule, E1> classRuleConsumer,
+      ThrowingConsumer<? super StartupProfileMethodRule, E2> methodRuleConsumer) {
     // Intentionally empty.
   }
 
@@ -49,11 +53,6 @@
   }
 
   @Override
-  public Collection<StartupProfileRule> getRules() {
-    return Collections.emptyList();
-  }
-
-  @Override
   public boolean isEmpty() {
     return true;
   }
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/StartupCompleteness.java b/src/main/java/com/android/tools/r8/experimental/startup/StartupCompleteness.java
index e3699f7..f45e4c0 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/StartupCompleteness.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/StartupCompleteness.java
@@ -4,7 +4,6 @@
 
 package com.android.tools.r8.experimental.startup;
 
-import com.android.tools.r8.experimental.startup.profile.StartupProfileRule;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexProgramClass;
@@ -74,11 +73,7 @@
 
   private Set<DexReference> computeStartupItems() {
     Set<DexReference> startupItems = Sets.newIdentityHashSet();
-    for (StartupProfileRule startupItem : startupProfile.getRules()) {
-      startupItem.accept(
-          startupClass -> startupItems.add(startupClass.getReference()),
-          startupMethod -> startupItems.add(startupMethod.getReference()));
-    }
+    startupProfile.forEachRule(rule -> startupItems.add(rule.getReference()));
     return startupItems;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/StartupProfile.java b/src/main/java/com/android/tools/r8/experimental/startup/StartupProfile.java
index 0689d7c..747097f 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/StartupProfile.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/StartupProfile.java
@@ -30,6 +30,7 @@
 import com.android.tools.r8.synthesis.SyntheticItems;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.Reporter;
+import com.android.tools.r8.utils.ThrowingConsumer;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedHashMap;
@@ -87,7 +88,7 @@
   public static StartupProfile merge(Collection<StartupProfile> startupProfiles) {
     Builder builder = builder();
     for (StartupProfile startupProfile : startupProfiles) {
-      startupProfile.getRules().forEach(builder::addStartupItem);
+      startupProfile.forEachRule(builder::addStartupItem);
     }
     return builder.build();
   }
@@ -131,9 +132,10 @@
     return StartupProfile.merge(startupProfiles);
   }
 
-  public abstract boolean isStartupClass(DexType type);
+  public abstract <E extends Exception> void forEachRule(
+      ThrowingConsumer<? super StartupProfileRule, E> consumer) throws E;
 
-  public abstract Collection<StartupProfileRule> getRules();
+  public abstract boolean isStartupClass(DexType type);
 
   public abstract boolean isEmpty();
 
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/StartupProfileProviderUtils.java b/src/main/java/com/android/tools/r8/experimental/startup/StartupProfileProviderUtils.java
index e5b6b58..ff5b0e9 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/StartupProfileProviderUtils.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/StartupProfileProviderUtils.java
@@ -61,10 +61,13 @@
     startupProfileProvider.getStartupProfile(startupProfileBuilder);
     // Serialize the startup items.
     StringBuilder resultBuilder = new StringBuilder();
-    for (StartupProfileRule startupItem : startupProfileBuilder.build().getRules()) {
-      startupItem.write(resultBuilder);
-      resultBuilder.append('\n');
-    }
+    StartupProfile startupProfile = startupProfileBuilder.build();
+    startupProfile.forEachRule(rule -> writeRule(rule, resultBuilder));
     return resultBuilder.toString();
   }
+
+  private static void writeRule(StartupProfileRule rule, Appendable appendable) throws IOException {
+    rule.write(appendable);
+    appendable.append('\n');
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/NonEmptyStartupProfile.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/NonEmptyStartupProfile.java
index 4b35a4b..4cec4e9 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/profile/NonEmptyStartupProfile.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/profile/NonEmptyStartupProfile.java
@@ -17,7 +17,6 @@
 import com.android.tools.r8.synthesis.SyntheticItems;
 import com.android.tools.r8.utils.SetUtils;
 import com.android.tools.r8.utils.ThrowingConsumer;
-import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.Set;
 import java.util.function.BiConsumer;
@@ -45,11 +44,17 @@
   }
 
   @Override
+  public <E extends Exception> void forEachRule(
+      ThrowingConsumer<? super StartupProfileRule, E> consumer) throws E {
+    forEachRule(consumer, consumer);
+  }
+
+  @Override
   public <E1 extends Exception, E2 extends Exception> void forEachRule(
-      ThrowingConsumer<StartupProfileClassRule, E1> classRuleConsumer,
-      ThrowingConsumer<StartupProfileMethodRule, E2> methodRuleConsumer)
+      ThrowingConsumer<? super StartupProfileClassRule, E1> classRuleConsumer,
+      ThrowingConsumer<? super StartupProfileMethodRule, E2> methodRuleConsumer)
       throws E1, E2 {
-    for (StartupProfileRule rule : getRules()) {
+    for (StartupProfileRule rule : startupRules.values()) {
       rule.accept(classRuleConsumer, methodRuleConsumer);
     }
   }
@@ -65,11 +70,6 @@
   }
 
   @Override
-  public Collection<StartupProfileRule> getRules() {
-    return startupRules.values();
-  }
-
-  @Override
   public boolean isEmpty() {
     return false;
   }
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileClassRule.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileClassRule.java
index c474ff2..8da68cf 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileClassRule.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileClassRule.java
@@ -33,8 +33,8 @@
 
   @Override
   public <E1 extends Exception, E2 extends Exception> void accept(
-      ThrowingConsumer<StartupProfileClassRule, E1> classConsumer,
-      ThrowingConsumer<StartupProfileMethodRule, E2> methodConsumer)
+      ThrowingConsumer<? super StartupProfileClassRule, E1> classConsumer,
+      ThrowingConsumer<? super StartupProfileMethodRule, E2> methodConsumer)
       throws E1 {
     classConsumer.accept(this);
   }
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileMethodRule.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileMethodRule.java
index 0a3a36a..54a7b17 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileMethodRule.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileMethodRule.java
@@ -33,8 +33,8 @@
 
   @Override
   public <E1 extends Exception, E2 extends Exception> void accept(
-      ThrowingConsumer<StartupProfileClassRule, E1> classConsumer,
-      ThrowingConsumer<StartupProfileMethodRule, E2> methodConsumer)
+      ThrowingConsumer<? super StartupProfileClassRule, E1> classConsumer,
+      ThrowingConsumer<? super StartupProfileMethodRule, E2> methodConsumer)
       throws E2 {
     methodConsumer.accept(this);
   }
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileRule.java b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileRule.java
index 200d364..64dbb2c 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileRule.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/profile/StartupProfileRule.java
@@ -14,8 +14,8 @@
     implements AbstractProfileRule, Comparable<StartupProfileRule> {
 
   public abstract <E1 extends Exception, E2 extends Exception> void accept(
-      ThrowingConsumer<StartupProfileClassRule, E1> classConsumer,
-      ThrowingConsumer<StartupProfileMethodRule, E2> methodConsumer)
+      ThrowingConsumer<? super StartupProfileClassRule, E1> classConsumer,
+      ThrowingConsumer<? super StartupProfileMethodRule, E2> methodConsumer)
       throws E1, E2;
 
   public abstract <T> T apply(
diff --git a/src/main/java/com/android/tools/r8/profile/AbstractProfile.java b/src/main/java/com/android/tools/r8/profile/AbstractProfile.java
index 87b5656..ff8c494 100644
--- a/src/main/java/com/android/tools/r8/profile/AbstractProfile.java
+++ b/src/main/java/com/android/tools/r8/profile/AbstractProfile.java
@@ -16,8 +16,8 @@
   boolean containsMethodRule(DexMethod method);
 
   <E1 extends Exception, E2 extends Exception> void forEachRule(
-      ThrowingConsumer<ClassRule, E1> classRuleConsumer,
-      ThrowingConsumer<MethodRule, E2> methodRuleConsumer)
+      ThrowingConsumer<? super ClassRule, E1> classRuleConsumer,
+      ThrowingConsumer<? super MethodRule, E2> methodRuleConsumer)
       throws E1, E2;
 
   ClassRule getClassRule(DexType type);
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfile.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfile.java
index 7ab727d..e42e8ba 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfile.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfile.java
@@ -71,8 +71,8 @@
 
   @Override
   public <E1 extends Exception, E2 extends Exception> void forEachRule(
-      ThrowingConsumer<ArtProfileClassRule, E1> classRuleConsumer,
-      ThrowingConsumer<ArtProfileMethodRule, E2> methodRuleConsumer)
+      ThrowingConsumer<? super ArtProfileClassRule, E1> classRuleConsumer,
+      ThrowingConsumer<? super ArtProfileMethodRule, E2> methodRuleConsumer)
       throws E1, E2 {
     for (ArtProfileRule rule : rules.values()) {
       rule.accept(classRuleConsumer, methodRuleConsumer);
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRule.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRule.java
index 625d92f..55590a0 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRule.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileClassRule.java
@@ -32,8 +32,8 @@
 
   @Override
   public <E1 extends Exception, E2 extends Exception> void accept(
-      ThrowingConsumer<ArtProfileClassRule, E1> classRuleConsumer,
-      ThrowingConsumer<ArtProfileMethodRule, E2> methodRuleConsumer)
+      ThrowingConsumer<? super ArtProfileClassRule, E1> classRuleConsumer,
+      ThrowingConsumer<? super ArtProfileMethodRule, E2> methodRuleConsumer)
       throws E1 {
     classRuleConsumer.accept(this);
   }
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRule.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRule.java
index 1440b8b..4b417c9 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRule.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileMethodRule.java
@@ -35,8 +35,8 @@
 
   @Override
   public <E1 extends Exception, E2 extends Exception> void accept(
-      ThrowingConsumer<ArtProfileClassRule, E1> classRuleConsumer,
-      ThrowingConsumer<ArtProfileMethodRule, E2> methodRuleConsumer)
+      ThrowingConsumer<? super ArtProfileClassRule, E1> classRuleConsumer,
+      ThrowingConsumer<? super ArtProfileMethodRule, E2> methodRuleConsumer)
       throws E2 {
     methodRuleConsumer.accept(this);
   }
diff --git a/src/main/java/com/android/tools/r8/profile/art/ArtProfileRule.java b/src/main/java/com/android/tools/r8/profile/art/ArtProfileRule.java
index bb0bcc1..39f541f 100644
--- a/src/main/java/com/android/tools/r8/profile/art/ArtProfileRule.java
+++ b/src/main/java/com/android/tools/r8/profile/art/ArtProfileRule.java
@@ -14,8 +14,8 @@
 public abstract class ArtProfileRule implements Comparable<ArtProfileRule>, AbstractProfileRule {
 
   public abstract <E1 extends Exception, E2 extends Exception> void accept(
-      ThrowingConsumer<ArtProfileClassRule, E1> classRuleConsumer,
-      ThrowingConsumer<ArtProfileMethodRule, E2> methodRuleConsumer)
+      ThrowingConsumer<? super ArtProfileClassRule, E1> classRuleConsumer,
+      ThrowingConsumer<? super ArtProfileMethodRule, E2> methodRuleConsumer)
       throws E1, E2;
 
   public abstract <T, E1 extends Exception, E2 extends Exception> T apply(
diff --git a/src/test/java/com/android/tools/r8/D8CommandTest.java b/src/test/java/com/android/tools/r8/D8CommandTest.java
index f22ce21..87b5338 100644
--- a/src/test/java/com/android/tools/r8/D8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/D8CommandTest.java
@@ -33,6 +33,7 @@
 import com.android.tools.r8.utils.ExtractMarkerUtils;
 import com.android.tools.r8.utils.FileUtils;
 import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.ListUtils;
 import com.android.tools.r8.utils.ThreadUtils;
 import com.android.tools.r8.utils.ZipUtils;
 import com.google.common.collect.ImmutableList;
@@ -812,7 +813,8 @@
 
     // Verify we found the same rule.
     StartupProfile startupProfile = startupProfileBuilder.build();
-    Collection<StartupProfileRule> startupItems = startupProfile.getRules();
+    Collection<StartupProfileRule> startupItems =
+        ListUtils.newArrayList(consumer -> startupProfile.forEachRule(consumer::accept));
     assertEquals(1, startupItems.size());
     StartupProfileRule startupItem = startupItems.iterator().next();
     startupItem.accept(