Account for isMutable call after inlining of edition 2023 builder

Change-Id: I5cb96dfec5632d86f2d125d485854a6857fc919b
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedMessageLiteBuilderShrinker.java b/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedMessageLiteBuilderShrinker.java
index 4c9ab2c..04c491e 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedMessageLiteBuilderShrinker.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedMessageLiteBuilderShrinker.java
@@ -493,6 +493,7 @@
 
       // MessageLite and GeneratedMessageLite heuristics.
       alwaysInlineCreateBuilderFromGeneratedMessageLite();
+      alwaysInlineNewMutableInstanceFromGeneratedMessageLite();
       neverMergeMessageLite();
 
       // * extends GeneratedMessageLite heuristics.
@@ -534,6 +535,10 @@
       alwaysInline.add(references.generatedMessageLiteMethods.createBuilderMethod);
     }
 
+    private void alwaysInlineNewMutableInstanceFromGeneratedMessageLite() {
+      alwaysInline.add(references.generatedMessageLiteMethods.newMutableInstanceMethod);
+    }
+
     private void neverMergeGeneratedMessageLiteBuilder() {
       // For consistency, never merge the GeneratedMessageLite builders. These will only have a
       // unique subtype if the application has a single proto message, which mostly happens during
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/proto/ProtoReferences.java b/src/main/java/com/android/tools/r8/ir/analysis/proto/ProtoReferences.java
index 812c0ee..8bacc2d 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/proto/ProtoReferences.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/proto/ProtoReferences.java
@@ -283,6 +283,7 @@
     public final DexMethod createBuilderMethod;
     public final DexMethod dynamicMethodBridgeMethod;
     public final DexMethod dynamicMethodBridgeMethodWithObject;
+    public final DexMethod newMutableInstanceMethod;
     public final DexMethod newRepeatedGeneratedExtension;
     public final DexMethod newSingularGeneratedExtension;
 
@@ -303,6 +304,11 @@
               dexItemFactory.createProto(
                   dexItemFactory.objectType, methodToInvokeType, dexItemFactory.objectType),
               "dynamicMethod");
+      newMutableInstanceMethod =
+          dexItemFactory.createMethod(
+              generatedMessageLiteType,
+              dexItemFactory.createProto(generatedMessageLiteType),
+              "newMutableInstance");
       newRepeatedGeneratedExtension =
           dexItemFactory.createMethod(
               generatedMessageLiteType,
diff --git a/src/test/java/com/android/tools/r8/internal/proto/ProtoBuilderShrinkingTest.java b/src/test/java/com/android/tools/r8/internal/proto/ProtoBuilderShrinkingTest.java
index 40560ff..dfd201a 100644
--- a/src/test/java/com/android/tools/r8/internal/proto/ProtoBuilderShrinkingTest.java
+++ b/src/test/java/com/android/tools/r8/internal/proto/ProtoBuilderShrinkingTest.java
@@ -260,9 +260,25 @@
         outputInspector.clazz("com.google.protobuf.GeneratedMessageLite");
     assertThat(generatedMessageLiteClassSubject, isPresent());
 
+    MethodSubject computeSerializedSizeMethodSubject =
+        generatedMessageLiteClassSubject.uniqueMethodWithOriginalName("computeSerializedSize");
+
+    MethodSubject equalsMethodSubject =
+        generatedMessageLiteClassSubject.uniqueMethodWithOriginalName("equals");
+
     MethodSubject isInitializedMethodSubject =
         generatedMessageLiteClassSubject.uniqueMethodWithOriginalName("isInitialized");
 
+    MethodSubject isMutableMethodSubject =
+        generatedMessageLiteClassSubject.uniqueMethodWithOriginalName("isMutable");
+
+    List<MethodSubject> allowList =
+        ImmutableList.of(
+            computeSerializedSizeMethodSubject,
+            equalsMethodSubject,
+            isInitializedMethodSubject,
+            isMutableMethodSubject);
+
     DexType methodToInvokeType =
         outputInspector.clazz(METHOD_TO_INVOKE_ENUM).getDexProgramClass().getType();
     for (String main : config.getMainClasses()) {
@@ -270,23 +286,21 @@
       assertThat(mainMethodSubject, isPresent());
 
       // Verify that the calls to GeneratedMessageLite.createBuilder() have been inlined.
-      // TODO(b/339100248): Investigate inadequate inlining with edition2023.
-      if (protoRuntime.isLegacy()) {
-        assertTrue(
-            mainMethodSubject
-                .streamInstructions()
-                .filter(InstructionSubject::isInvoke)
-                .map(InstructionSubject::getMethod)
-                .allMatch(
-                    method ->
-                        method.getHolderType()
-                                != generatedMessageLiteClassSubject.getDexProgramClass().getType()
-                            || (isInitializedMethodSubject.isPresent()
-                                && method
-                                    == isInitializedMethodSubject
-                                        .getProgramMethod()
-                                        .getReference())));
-      }
+      assertTrue(
+          mainMethodSubject
+              .streamInstructions()
+              .filter(InstructionSubject::isInvoke)
+              .map(InstructionSubject::getMethod)
+              .allMatch(
+                  method ->
+                      method.getHolderType()
+                              != generatedMessageLiteClassSubject.getDexProgramClass().getType()
+                          || allowList.stream()
+                              .anyMatch(
+                                  m ->
+                                      m.isPresent()
+                                          && method.isIdenticalTo(
+                                              m.getProgramMethod().getReference()))));
 
       // Verify that there are no accesses to MethodToInvoke after inlining createBuilder() -- and
       // specifically no accesses to MethodToInvoke.NEW_BUILDER.