Transition live proto messages to being instantiated

Change-Id: Ia5669fd7d0d656c6e56ffcb3076179cd3f4ce963
diff --git a/src/main/java/com/android/tools/r8/graph/analysis/EnqueuerAnalysis.java b/src/main/java/com/android/tools/r8/graph/analysis/EnqueuerAnalysis.java
index 2b55be8..8374410 100644
--- a/src/main/java/com/android/tools/r8/graph/analysis/EnqueuerAnalysis.java
+++ b/src/main/java/com/android/tools/r8/graph/analysis/EnqueuerAnalysis.java
@@ -15,6 +15,9 @@
   /** Called when a class is found to be instantiated. */
   public void processNewlyInstantiatedClass(DexProgramClass clazz, DexEncodedMethod context) {}
 
+  /** Called when a class is found to be live. */
+  public void processNewlyLiveClass(DexProgramClass clazz, EnqueuerWorklist worklist) {}
+
   /** Called when a field is found to be live. */
   public void processNewlyLiveField(DexEncodedField field) {}
 
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java b/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java
index 943d559..bf6c8b1 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java
@@ -6,6 +6,7 @@
 
 import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
 
+import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedField;
@@ -32,6 +33,7 @@
 import com.android.tools.r8.ir.optimize.info.FieldOptimizationInfo;
 import com.android.tools.r8.shaking.Enqueuer;
 import com.android.tools.r8.shaking.EnqueuerWorklist;
+import com.android.tools.r8.shaking.InstantiationReason;
 import com.android.tools.r8.shaking.KeepReason;
 import com.android.tools.r8.utils.BitUtils;
 import com.android.tools.r8.utils.OptionalBool;
@@ -89,6 +91,34 @@
     this.references = protoShrinker.references;
   }
 
+  @Override
+  public void processNewlyLiveClass(DexProgramClass clazz, EnqueuerWorklist worklist) {
+    assert appView.appInfo().hasClassHierarchy();
+    AppInfoWithClassHierarchy appInfo = appView.appInfo().withClassHierarchy();
+    if (appInfo.isStrictSubtypeOf(clazz.type, references.generatedMessageLiteType)) {
+      markGeneratedMessageLiteSubtypeAsInstantiated(clazz, worklist);
+    }
+  }
+
+  private void markGeneratedMessageLiteSubtypeAsInstantiated(
+      DexProgramClass clazz, EnqueuerWorklist worklist) {
+    if (clazz.isAbstract()) {
+      assert clazz.type == references.extendableMessageType;
+      return;
+    }
+    DexEncodedMethod dynamicMethod = clazz.lookupVirtualMethod(references::isDynamicMethod);
+    if (dynamicMethod != null) {
+      worklist.enqueueMarkInstantiatedAction(
+          clazz,
+          dynamicMethod,
+          InstantiationReason.REFLECTION,
+          KeepReason.reflectiveUseIn(dynamicMethod));
+    } else {
+      assert false
+          : "Expected class `" + clazz.type.toSourceString() + "` to declare a dynamicMethod()";
+    }
+  }
+
   /**
    * When a dynamicMethod() of a proto message becomes live, then build the corresponding {@link
    * ProtoMessageInfo} object, and create a mapping from the holder to it.
@@ -557,8 +587,10 @@
     DexType baseMessageType = protoFieldInfo.getBaseMessageType(factory);
     if (baseMessageType != null) {
       ProtoMessageInfo protoMessageInfo = getOrCreateProtoMessageInfo(baseMessageType);
-      assert protoMessageInfo != null;
-      return reachesMapOrRequiredField(protoMessageInfo);
+      if (protoMessageInfo != null) {
+        return reachesMapOrRequiredField(protoMessageInfo);
+      }
+      assert false : "Unable to find proto message info for `" + baseMessageType + "`";
     }
     return false;
   }
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 422ec43..200562d 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -1325,6 +1325,8 @@
     rootSet.forEachDependentStaticMember(holder, appView, this::enqueueDependentItem);
     compatEnqueueHolderIfDependentNonStaticMember(
         holder, rootSet.getDependentKeepClassCompatRule(holder.getType()));
+
+    analyses.forEach(analysis -> analysis.processNewlyLiveClass(holder, workList));
   }
 
   private void ensureMethodsContinueToWidenAccess(DexClass clazz) {
diff --git a/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java b/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
index 45e61a4..c795bcc 100644
--- a/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
+++ b/src/main/java/com/android/tools/r8/shaking/EnqueuerWorklist.java
@@ -270,7 +270,7 @@
 
   // TODO(b/142378367): Context is the containing method that is cause of the instantiation.
   // Consider updating call sites with the context information to increase precision where possible.
-  void enqueueMarkInstantiatedAction(
+  public void enqueueMarkInstantiatedAction(
       DexProgramClass clazz,
       DexEncodedMethod context,
       InstantiationReason instantiationReason,
diff --git a/src/test/java/com/android/tools/r8/internal/Gmail18082615TreeShakeJarVerificationTest.java b/src/test/java/com/android/tools/r8/internal/Gmail18082615TreeShakeJarVerificationTest.java
index 7d04499..183ee3e 100644
--- a/src/test/java/com/android/tools/r8/internal/Gmail18082615TreeShakeJarVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/Gmail18082615TreeShakeJarVerificationTest.java
@@ -45,13 +45,14 @@
             .addKeepRuleFiles(
                 Paths.get(base).resolve(BASE_PG_CONF),
                 Paths.get(ToolHelper.PROGUARD_SETTINGS_FOR_INTERNAL_APPS, PG_CONF))
-            .allowDiagnosticInfoMessages()
+            .allowDiagnosticMessages()
             .allowUnusedProguardConfigurationRules()
             .compile()
             .assertAllInfoMessagesMatch(
                 anyOf(
                     equalTo("Ignoring option: -optimizations"),
-                    containsString("Proguard configuration rule does not match anything")));
+                    containsString("Proguard configuration rule does not match anything")))
+            .assertAllWarningMessagesMatch(containsString("Ignoring option:"));
 
     int appSize = compileResult.app.applicationSize();
     assertTrue("Expected max size of " + MAX_SIZE+ ", got " + appSize, appSize < MAX_SIZE);
diff --git a/third_party/proguardsettings.tar.gz.sha1 b/third_party/proguardsettings.tar.gz.sha1
index d5c183a..af7dff0 100644
--- a/third_party/proguardsettings.tar.gz.sha1
+++ b/third_party/proguardsettings.tar.gz.sha1
@@ -1 +1 @@
-7bb1badb721635d2baa7b63aab1e3a67434f94dd
\ No newline at end of file
+12c2e310110cdccb6aa5a37c287456b8c4bfe3d6
\ No newline at end of file