Reproduce proto builder optimization bug

Change-Id: I8fbf0a3224d32e65bfd2da7010a130e4ad5cdc04
Bug: 155416893
diff --git a/src/test/examplesProto/proto2/BuilderOnlyReferencedFromDynamicMethodTestClass.java b/src/test/examplesProto/proto2/BuilderOnlyReferencedFromDynamicMethodTestClass.java
new file mode 100644
index 0000000..e3707dc
--- /dev/null
+++ b/src/test/examplesProto/proto2/BuilderOnlyReferencedFromDynamicMethodTestClass.java
@@ -0,0 +1,24 @@
+// Copyright (c) 2020, 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 proto2;
+
+import com.android.tools.r8.proto2.TestProto.Primitives;
+import com.google.protobuf.GeneratedMessageLite;
+import com.google.protobuf.InvalidProtocolBufferException;
+
+public class BuilderOnlyReferencedFromDynamicMethodTestClass {
+
+  public static void main(String[] args) {
+    GeneratedMessageLite<?, ?> primitivesInDisguise;
+    try {
+      primitivesInDisguise = Primitives.parseFrom(new byte[0]);
+    } catch (InvalidProtocolBufferException e) {
+      System.out.println("Unexpected exception: " + e);
+      throw new RuntimeException(e);
+    }
+    Primitives primitives = (Primitives) primitivesInDisguise.toBuilder().build();
+    Printer.print(primitives);
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderOnlyReferencedFromDynamicMethodTest.java b/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderOnlyReferencedFromDynamicMethodTest.java
new file mode 100644
index 0000000..2153126
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderOnlyReferencedFromDynamicMethodTest.java
@@ -0,0 +1,74 @@
+// Copyright (c) 2020, 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.internal.proto;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.google.common.collect.ImmutableList;
+import java.nio.file.Path;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class Proto2BuilderOnlyReferencedFromDynamicMethodTest extends ProtoShrinkingTestBase {
+
+  private static final String MAIN = "proto2.BuilderOnlyReferencedFromDynamicMethodTestClass";
+
+  private static List<Path> PROGRAM_FILES =
+      ImmutableList.of(PROTO2_EXAMPLES_JAR, PROTO2_PROTO_JAR, PROTOBUF_LITE_JAR);
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().build();
+  }
+
+  public Proto2BuilderOnlyReferencedFromDynamicMethodTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .addProgramFiles(PROGRAM_FILES)
+        .addKeepMainRule(MAIN)
+        .addKeepRuleFiles(PROTOBUF_LITE_PROGUARD_RULES)
+        .allowAccessModification()
+        .allowDiagnosticMessages()
+        .allowUnusedProguardConfigurationRules()
+        .enableProtoShrinking()
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .assertAllInfoMessagesMatch(
+            containsString("Proguard configuration rule does not match anything"))
+        .assertAllWarningMessagesMatch(equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
+        .inspect(this::inspect)
+        .run(parameters.getRuntime(), MAIN)
+        .assertFailureWithErrorThatMatches(containsString("UnsupportedOperationException"));
+    // TODO(b/155416893): Should succeed with the following output.
+    // .assertSuccessWithOutputLines(
+    //     "false", "0", "false", "", "false", "0", "false", "0", "false", "");
+  }
+
+  private void inspect(CodeInspector outputInspector) {
+    verifyBuilderIsAbsent(outputInspector);
+  }
+
+  private void verifyBuilderIsAbsent(CodeInspector outputInspector) {
+    assertThat(
+        outputInspector.clazz("com.android.tools.r8.proto2.TestProto$Primitives$Builder"),
+        not(isPresent()));
+  }
+}