Disallow optimizations for modeled proto methods

Change-Id: I3fcc78ef714baad9795568abc1bed9e4789f39d0
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedMessageLiteShrinker.java b/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedMessageLiteShrinker.java
index 1053b49..4e36bed 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedMessageLiteShrinker.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedMessageLiteShrinker.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.ir.analysis.proto;
 
+import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
 import static com.android.tools.r8.ir.analysis.proto.ProtoUtils.getInfoValueFromMessageInfoConstructionInvoke;
 import static com.android.tools.r8.ir.analysis.proto.ProtoUtils.getObjectsValueFromMessageInfoConstructionInvoke;
 import static com.android.tools.r8.ir.analysis.proto.ProtoUtils.setObjectsValueForMessageInfoConstructionInvoke;
@@ -11,6 +12,7 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.analysis.proto.schema.ProtoMessageInfo;
 import com.android.tools.r8.ir.analysis.proto.schema.ProtoObject;
@@ -30,7 +32,7 @@
 import com.android.tools.r8.ir.conversion.IRConverter;
 import com.android.tools.r8.ir.conversion.OneTimeMethodProcessor;
 import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackIgnore;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.shaking.DependentMinimumKeepInfoCollection;
 import com.android.tools.r8.utils.Timing;
 import com.android.tools.r8.utils.collections.SortedProgramMethodSet;
 import java.util.List;
@@ -40,7 +42,7 @@
 
 public class GeneratedMessageLiteShrinker {
 
-  private final AppView<AppInfoWithLiveness> appView;
+  private final AppView<?> appView;
   private final RawMessageInfoDecoder decoder;
   private final RawMessageInfoEncoder encoder;
   private final ProtoReferences references;
@@ -49,9 +51,7 @@
   private final TypeElement stringType;
 
   public GeneratedMessageLiteShrinker(
-      AppView<AppInfoWithLiveness> appView,
-      RawMessageInfoDecoder decoder,
-      ProtoReferences references) {
+      AppView<?> appView, RawMessageInfoDecoder decoder, ProtoReferences references) {
     this.appView = appView;
     this.decoder = decoder;
     this.encoder = new RawMessageInfoEncoder(appView.dexItemFactory());
@@ -64,6 +64,45 @@
     this.stringType = TypeElement.stringClassType(appView, Nullability.definitelyNotNull());
   }
 
+  public void extendRootSet(DependentMinimumKeepInfoCollection dependentMinimumKeepInfo) {
+    // Disable optimizations for various methods that are modeled, to ensure that we can still
+    // recognize the uses of these methods even after optimizations have been run.
+    DexProgramClass generatedMessageLiteClass =
+        asProgramClassOrNull(
+            appView
+                .appInfo()
+                .definitionForWithoutExistenceAssert(references.generatedMessageLiteType));
+    if (generatedMessageLiteClass != null) {
+      ProgramMethod dynamicMethod =
+          generatedMessageLiteClass.lookupProgramMethod(references.dynamicMethod);
+      if (dynamicMethod != null) {
+        dependentMinimumKeepInfo
+            .getOrCreateUnconditionalMinimumKeepInfoFor(dynamicMethod.getReference())
+            .disallowOptimization();
+      }
+
+      ProgramMethod newRepeatedGeneratedExtensionMethod =
+          generatedMessageLiteClass.lookupProgramMethod(
+              references.generatedMessageLiteMethods.newRepeatedGeneratedExtension);
+      if (newRepeatedGeneratedExtensionMethod != null) {
+        dependentMinimumKeepInfo
+            .getOrCreateUnconditionalMinimumKeepInfoFor(
+                newRepeatedGeneratedExtensionMethod.getReference())
+            .disallowOptimization();
+      }
+
+      ProgramMethod newSingularGeneratedExtensionMethod =
+          generatedMessageLiteClass.lookupProgramMethod(
+              references.generatedMessageLiteMethods.newSingularGeneratedExtension);
+      if (newSingularGeneratedExtensionMethod != null) {
+        dependentMinimumKeepInfo
+            .getOrCreateUnconditionalMinimumKeepInfoFor(
+                newSingularGeneratedExtensionMethod.getReference())
+            .disallowOptimization();
+      }
+    }
+  }
+
   public void run(IRCode code) {
     ProgramMethod method = code.context();
     if (references.isDynamicMethod(method.getReference())) {
@@ -91,7 +130,7 @@
   private void forEachDynamicMethod(Consumer<ProgramMethod> consumer) {
     DexItemFactory dexItemFactory = appView.dexItemFactory();
     appView
-        .appInfo()
+        .appInfoWithLiveness()
         .forEachInstantiatedSubType(
             references.generatedMessageLiteType,
             clazz -> {
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
index 72a1510..bbe1773 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
@@ -355,6 +355,8 @@
         BottomUpClassHierarchyTraversal.forAllClasses(appView, subtypingInfo)
             .visit(appView.appInfo().classes(), this::propagateAssumeRules);
       }
+      appView.withGeneratedMessageLiteShrinker(
+          shrinker -> shrinker.extendRootSet(dependentMinimumKeepInfo));
       if (appView.options().protoShrinking().enableGeneratedMessageLiteBuilderShrinking) {
         GeneratedMessageLiteBuilderShrinker.addInliningHeuristicsForBuilderInlining(
             appView,