Implement first version of proto lite shrinker.
Bug:
Change-Id: Ia77e68cfd634f38954cdcbe1537fd86937ff9720
diff --git a/src/test/examples/enumproto/Enumproto.java b/src/test/examples/enumproto/Enumproto.java
new file mode 100644
index 0000000..9176378
--- /dev/null
+++ b/src/test/examples/enumproto/Enumproto.java
@@ -0,0 +1,66 @@
+// Copyright (c) 2017, 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 enumproto;
+
+
+import enumproto.GeneratedEnumProto.Enum;
+import enumproto.three.GeneratedEnumProto.EnumThree;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+public class Enumproto {
+
+ private static final byte[] WITH_ALL_FIELDS = new byte[]{6, 8, 42, 16, 2, 24, 3};
+ private static final byte[] WITH_DEFAULT_FOR_ENUM = new byte[]{2, 8, 42};
+
+
+ public static void main(String... args) throws IOException {
+ readProtoAndPrintDaEnum(WITH_ALL_FIELDS);
+ readProtoAndPrintDaEnum(WITH_DEFAULT_FOR_ENUM);
+ readProtoThreeAndPrintDaEnum(WITH_ALL_FIELDS);
+ readProtoThreeAndPrintDaEnum(WITH_DEFAULT_FOR_ENUM);
+ roundTrip(WITH_ALL_FIELDS);
+ roundTrip(WITH_DEFAULT_FOR_ENUM);
+ roundTripThree(WITH_ALL_FIELDS);
+ roundTripThree(WITH_DEFAULT_FOR_ENUM);
+ }
+
+ private static void readProtoAndPrintDaEnum(byte[] bytes) throws IOException {
+ ByteArrayInputStream input = new ByteArrayInputStream(bytes);
+ Enum.Builder builder = Enum.newBuilder();
+ builder.mergeDelimitedFrom(input);
+ Enum buffer = builder.build();
+ System.out.println(buffer.getEnum());
+ }
+
+ private static void readProtoThreeAndPrintDaEnum(byte[] bytes) throws IOException {
+ ByteArrayInputStream input = new ByteArrayInputStream(bytes);
+ EnumThree.Builder builder = EnumThree.newBuilder();
+ builder.mergeDelimitedFrom(input);
+ EnumThree buffer = builder.build();
+ System.out.println(buffer.getEnum());
+ }
+
+ private static void roundTrip(byte[] bytes) throws IOException {
+ ByteArrayInputStream input = new ByteArrayInputStream(bytes);
+ Enum.Builder builder = Enum.newBuilder();
+ builder.mergeDelimitedFrom(input);
+ Enum buffer = builder.build();
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ buffer.writeDelimitedTo(output);
+ readProtoAndPrintDaEnum(output.toByteArray());
+ }
+
+ private static void roundTripThree(byte[] bytes) throws IOException {
+ ByteArrayInputStream input = new ByteArrayInputStream(bytes);
+ EnumThree.Builder builder = EnumThree.newBuilder();
+ builder.mergeDelimitedFrom(input);
+ EnumThree buffer = builder.build();
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ buffer.writeDelimitedTo(output);
+ readProtoThreeAndPrintDaEnum(output.toByteArray());
+ }
+
+}
diff --git a/src/test/examples/enumproto/enum.proto b/src/test/examples/enumproto/enum.proto
new file mode 100644
index 0000000..0fa5695
--- /dev/null
+++ b/src/test/examples/enumproto/enum.proto
@@ -0,0 +1,25 @@
+// Copyright (c) 2017, 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.
+syntax = "proto2";
+package enumproto;
+
+option java_outer_classname = "GeneratedEnumProto";
+
+message Enum {
+ required int32 id = 1;
+ enum DaEnum {
+ UNKOWN = 0;
+ KNOWN = 1;
+ BELIEF = 2;
+ }
+ optional DaEnum enum = 2;
+ enum OtherEnum {
+ BLACK = 0;
+ RED = 1;
+ GREEN = 2;
+ OKALALALA = 3;
+ }
+ optional OtherEnum other = 3;
+}
+
diff --git a/src/test/examples/enumproto/enum_three.proto b/src/test/examples/enumproto/enum_three.proto
new file mode 100644
index 0000000..a2731fb
--- /dev/null
+++ b/src/test/examples/enumproto/enum_three.proto
@@ -0,0 +1,25 @@
+// Copyright (c) 2016, 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.
+syntax = "proto3";
+package enumproto.three;
+
+option java_outer_classname = "GeneratedEnumProto";
+
+message EnumThree {
+ int32 id = 1;
+ enum DaEnum {
+ UNKOWN = 0;
+ KNOWN = 1;
+ BELIEF = 2;
+ }
+ DaEnum enum = 2;
+ enum OtherEnum {
+ BLACK = 0;
+ RED = 1;
+ GREEN = 2;
+ OKALALALA = 3;
+ }
+ OtherEnum other = 3;
+}
+
diff --git a/src/test/examples/enumproto/keep-rules.txt b/src/test/examples/enumproto/keep-rules.txt
new file mode 100644
index 0000000..088f88f
--- /dev/null
+++ b/src/test/examples/enumproto/keep-rules.txt
@@ -0,0 +1,12 @@
+# Copyright (c) 2017, 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.
+
+# Keep the application entry point. Get rid of everything that is not
+# reachable from there.
+-keep public class enumproto.Enumproto {
+ public static void main(...);
+}
+
+# allow access modification to enable minification
+-allowaccessmodification
diff --git a/src/test/examples/nestedproto1/Nestedproto.java b/src/test/examples/nestedproto1/Nestedproto.java
new file mode 100644
index 0000000..fe1a535
--- /dev/null
+++ b/src/test/examples/nestedproto1/Nestedproto.java
@@ -0,0 +1,31 @@
+// Copyright (c) 2017, 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 nestedproto1;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import nestedproto1.GeneratedNestedProto.Outer;
+
+public class Nestedproto {
+
+ private static final byte[] NESTED_MESSAGE_WITH_BOTH = new byte[] {25, 8, 42, 18, 12, 8, 1, 18, 8,
+ 105, 110, 110, 101, 114, 79, 110, 101, 26, 7, 8, 2, 21, 0, 0, -10, 66};
+
+ private static final byte[] NESTED_MESSAGE_WITH_ONE = new byte[]{16, 8, 42, 18, 12, 8, 1, 18, 8,
+ 105,
+ 110, 110, 101, 114, 79, 110, 101};
+
+ public static void main(String... args) throws IOException {
+ testWith(NESTED_MESSAGE_WITH_BOTH);
+ testWith(NESTED_MESSAGE_WITH_ONE);
+ }
+
+ public static void testWith(byte[] data) throws IOException {
+ ByteArrayInputStream input = new ByteArrayInputStream(data);
+ Outer.Builder builder = Outer.newBuilder();
+ builder.mergeDelimitedFrom(input);
+ Outer outer = builder.build();
+ System.out.println(outer.getInner().getOther());
+ }
+}
diff --git a/src/test/examples/nestedproto1/keep-rules.txt b/src/test/examples/nestedproto1/keep-rules.txt
new file mode 100644
index 0000000..1c47672
--- /dev/null
+++ b/src/test/examples/nestedproto1/keep-rules.txt
@@ -0,0 +1,12 @@
+# Copyright (c) 2017, 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.
+
+# Keep the application entry point. Get rid of everything that is not
+# reachable from there.
+-keep public class nestedproto1.Nestedproto {
+ public static void main(...);
+}
+
+# allow access modification to enable minification
+-allowaccessmodification
diff --git a/src/test/examples/nestedproto1/nested.proto b/src/test/examples/nestedproto1/nested.proto
new file mode 100644
index 0000000..0d05749
--- /dev/null
+++ b/src/test/examples/nestedproto1/nested.proto
@@ -0,0 +1,24 @@
+// Copyright (c) 2016, 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.
+syntax = "proto2";
+package nestedproto1;
+
+option java_outer_classname = "GeneratedNestedProto";
+
+message NestedOne {
+ required int32 id = 1;
+ optional string other = 2;
+}
+
+message NestedTwo {
+ required int32 id = 1;
+ optional float other = 2;
+}
+
+message Outer {
+ required int32 id = 1;
+ required NestedOne inner = 2;
+ optional NestedTwo inner2 = 3;
+}
+
diff --git a/src/test/examples/nestedproto2/Nestedproto.java b/src/test/examples/nestedproto2/Nestedproto.java
new file mode 100644
index 0000000..59217de
--- /dev/null
+++ b/src/test/examples/nestedproto2/Nestedproto.java
@@ -0,0 +1,33 @@
+// Copyright (c) 2017, 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 nestedproto2;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import nestedproto2.GeneratedNestedProto.Outer;
+
+public class Nestedproto {
+
+ private static final byte[] NESTED_MESSAGE_WITH_BOTH = new byte[]{25, 8, 42, 18, 12, 8, 1, 18, 8,
+ 105, 110, 110, 101, 114, 79, 110, 101, 26, 7, 8, 2, 21, 0, 0, -10, 66};
+
+ private static final byte[] NESTED_MESSAGE_WITH_ONE = new byte[]{16, 8, 42, 18, 12, 8, 1, 18, 8,
+ 105,
+ 110, 110, 101, 114, 79, 110, 101};
+
+ // Test that all fields remain when roundtripping with removed fields.
+ public static void main(String... args) throws IOException {
+ testWith(NESTED_MESSAGE_WITH_BOTH);
+ testWith(NESTED_MESSAGE_WITH_ONE);
+ }
+
+ private static void testWith(byte[] data) throws IOException {
+ ByteArrayInputStream input = new ByteArrayInputStream(data);
+ Outer.Builder builder = Outer.newBuilder();
+ builder.mergeDelimitedFrom(input);
+ builder.setId(1982);
+ Outer outer = builder.build();
+ outer.writeTo(System.out);
+ }
+}
diff --git a/src/test/examples/nestedproto2/keep-rules.txt b/src/test/examples/nestedproto2/keep-rules.txt
new file mode 100644
index 0000000..87c9218
--- /dev/null
+++ b/src/test/examples/nestedproto2/keep-rules.txt
@@ -0,0 +1,12 @@
+# Copyright (c) 2017, 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.
+
+# Keep the application entry point. Get rid of everything that is not
+# reachable from there.
+-keep public class nestedproto2.Nestedproto {
+ public static void main(...);
+}
+
+# allow access modification to enable minification
+-allowaccessmodification
diff --git a/src/test/examples/nestedproto2/nested.proto b/src/test/examples/nestedproto2/nested.proto
new file mode 100644
index 0000000..ac56f40
--- /dev/null
+++ b/src/test/examples/nestedproto2/nested.proto
@@ -0,0 +1,24 @@
+// Copyright (c) 2016, 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.
+syntax = "proto2";
+package nestedproto2;
+
+option java_outer_classname = "GeneratedNestedProto";
+
+message NestedOne {
+ required int32 id = 1;
+ optional string other = 2;
+}
+
+message NestedTwo {
+ required int32 id = 1;
+ optional float other = 2;
+}
+
+message Outer {
+ required int32 id = 1;
+ required NestedOne inner = 2;
+ optional NestedTwo inner2 = 3;
+}
+
diff --git a/src/test/examples/oneofproto/Oneofproto.java b/src/test/examples/oneofproto/Oneofproto.java
new file mode 100644
index 0000000..261705f
--- /dev/null
+++ b/src/test/examples/oneofproto/Oneofproto.java
@@ -0,0 +1,38 @@
+// Copyright (c) 2017, 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 oneofproto;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import oneofproto.GeneratedOneOfProto.Oneof;
+
+public class Oneofproto {
+
+ private static final byte[] WITH_BOOL_FIELD = new byte[]{4, 8, 42, 24, 1};
+ private static final byte[] WITH_FLOAT_FIELD = new byte[]{7, 8, 42, 21, 0, 0, -10, 66};
+ private static final byte[] WITH_STRING_FIELD = new byte[]{9, 8, 42, 34, 5, 104, 101, 108, 108,
+ 111};
+ private static final byte[] WITH_NO_FIELD = new byte[]{2, 8, 42};
+
+
+ public static void main(String... args) throws IOException {
+ roundTrip(WITH_BOOL_FIELD);
+ roundTrip(WITH_FLOAT_FIELD);
+ roundTrip(WITH_STRING_FIELD);
+ roundTrip(WITH_NO_FIELD);
+ }
+
+ private static void roundTrip(byte[] data) throws IOException {
+ ByteArrayInputStream input = new ByteArrayInputStream(data);
+ Oneof.Builder builder = Oneof.newBuilder();
+ builder.mergeDelimitedFrom(input);
+ Oneof oneof = builder.build();
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ oneof.writeDelimitedTo(output);
+ System.out.println(Arrays.toString(output.toByteArray()));
+ }
+
+}
diff --git a/src/test/examples/oneofproto/keep-rules.txt b/src/test/examples/oneofproto/keep-rules.txt
new file mode 100644
index 0000000..70f00f1
--- /dev/null
+++ b/src/test/examples/oneofproto/keep-rules.txt
@@ -0,0 +1,12 @@
+# Copyright (c) 2017, 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.
+
+# Keep the application entry point. Get rid of everything that is not
+# reachable from there.
+-keep public class oneofproto.Oneofproto {
+ public static void main(...);
+}
+
+# allow access modification to enable minification
+-allowaccessmodification
diff --git a/src/test/examples/oneofproto/oneof.proto b/src/test/examples/oneofproto/oneof.proto
new file mode 100644
index 0000000..c5a67a1
--- /dev/null
+++ b/src/test/examples/oneofproto/oneof.proto
@@ -0,0 +1,17 @@
+// Copyright (c) 2016, 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.
+syntax = "proto2";
+package oneofproto;
+
+option java_outer_classname = "GeneratedOneOfProto";
+
+message Oneof {
+ required int32 id = 1;
+ oneof otherfields {
+ float floatField = 2;
+ bool boolField = 3;
+ string stringField = 4;
+ }
+}
+
diff --git a/src/test/examples/protowithexts/withexts.proto b/src/test/examples/protowithexts/withexts.proto
new file mode 100644
index 0000000..d384173
--- /dev/null
+++ b/src/test/examples/protowithexts/withexts.proto
@@ -0,0 +1,19 @@
+// Copyright (c) 2016, 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.
+syntax = "proto2";
+package protowithexts;
+
+option java_outer_classname = "GeneratedProtoWithExts";
+
+message Simple {
+ required int32 id = 1;
+
+ optional int32 other = 2;
+
+ extensions 10 to 19;
+}
+
+extend Simple {
+ optional string extra = 10;
+}
diff --git a/src/test/examples/repeatedproto/Repeatedproto.java b/src/test/examples/repeatedproto/Repeatedproto.java
new file mode 100644
index 0000000..280070d
--- /dev/null
+++ b/src/test/examples/repeatedproto/Repeatedproto.java
@@ -0,0 +1,22 @@
+// Copyright (c) 2017, 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 repeatedproto;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import repeatedproto.GeneratedRepeatedProto.Repeated;
+
+public class Repeatedproto {
+
+ private static final byte[] WITH_ALL_FIELDS = new byte[]{29, 8, 123, 18, 3, 111, 110, 101, 18, 3,
+ 116, 119, 111, 18, 5, 116, 104, 114, 101, 101, 24, 1, 34, 2, 8, 42, 34, 2, 8, 42};
+
+ public static void main(String... args) throws IOException {
+ ByteArrayInputStream input = new ByteArrayInputStream(WITH_ALL_FIELDS);
+ Repeated.Builder builder = Repeated.newBuilder();
+ builder.mergeDelimitedFrom(input);
+ Repeated repeated = builder.build();
+ System.out.println(repeated.getRepeatedList());
+ }
+}
diff --git a/src/test/examples/repeatedproto/keep-rules.txt b/src/test/examples/repeatedproto/keep-rules.txt
new file mode 100644
index 0000000..3d02352
--- /dev/null
+++ b/src/test/examples/repeatedproto/keep-rules.txt
@@ -0,0 +1,12 @@
+# Copyright (c) 2017, 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.
+
+# Keep the application entry point. Get rid of everything that is not
+# reachable from there.
+-keep public class repeatedproto.Repeatedproto {
+ public static void main(...);
+}
+
+# allow access modification to enable minification
+-allowaccessmodification
diff --git a/src/test/examples/repeatedproto/repeated.proto b/src/test/examples/repeatedproto/repeated.proto
new file mode 100644
index 0000000..7414e6f
--- /dev/null
+++ b/src/test/examples/repeatedproto/repeated.proto
@@ -0,0 +1,20 @@
+// Copyright (c) 2016, 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.
+syntax = "proto2";
+package repeatedproto;
+
+option java_outer_classname = "GeneratedRepeatedProto";
+
+message Repeated {
+ required int32 id = 1;
+ repeated string repeated = 2;
+ repeated bool other = 3;
+
+ message Sub {
+ required int32 value = 1;
+ }
+
+ repeated Sub sub = 4;
+}
+
diff --git a/src/test/examples/repeatedproto/repeated_three.proto b/src/test/examples/repeatedproto/repeated_three.proto
new file mode 100644
index 0000000..7da7881
--- /dev/null
+++ b/src/test/examples/repeatedproto/repeated_three.proto
@@ -0,0 +1,15 @@
+// Copyright (c) 2016, 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.
+syntax = "proto3";
+package repeatedproto.three;
+
+option java_outer_classname = "GeneratedRepeatedProto";
+
+
+message RepeatedThree {
+ int32 id = 1;
+ repeated string repeated = 2;
+ repeated bool other = 3;
+}
+
diff --git a/src/test/examples/simpleproto1/Simpleproto.java b/src/test/examples/simpleproto1/Simpleproto.java
new file mode 100644
index 0000000..d07ce8d
--- /dev/null
+++ b/src/test/examples/simpleproto1/Simpleproto.java
@@ -0,0 +1,56 @@
+// Copyright (c) 2017, 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 simpleproto1;
+
+import com.google.protobuf.UninitializedMessageException;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import simpleproto1.GeneratedSimpleProto.Simple;
+
+public class Simpleproto {
+
+ private static final byte[] WITH_REQUIRED_FIELDS = new byte[]{7, 8, 42, 21, 0, 0, -10, 66};
+ private static final byte[] WITH_MISSING_FIELD = new byte[]{2, 8, 42};
+
+
+ public static void main(String... args) throws IOException {
+ readProtoWithAllReqFields();
+ partialBuildFails();
+ partialReadFails();
+ }
+
+ private static void partialBuildFails() {
+ Simple.Builder builder = Simple.newBuilder();
+ builder.setId(32);
+ try {
+ builder.build();
+ } catch (UninitializedMessageException e) {
+ System.out.println("got exception");
+ }
+ }
+
+ private static void partialReadFails() throws IOException {
+ ByteArrayInputStream input = new ByteArrayInputStream(WITH_MISSING_FIELD);
+ Simple.Builder builder = Simple.newBuilder();
+ builder.mergeDelimitedFrom(input);
+ try {
+ builder.build();
+ } catch (UninitializedMessageException e) {
+ System.out.println("got exception");
+ }
+ }
+
+ private static void readProtoWithAllReqFields() throws IOException {
+ ByteArrayInputStream input = new ByteArrayInputStream(WITH_REQUIRED_FIELDS);
+ Simple.Builder builder = Simple.newBuilder();
+ builder.mergeDelimitedFrom(input);
+ Simple simple = builder.build();
+ ByteArrayOutputStream output = new ByteArrayOutputStream(WITH_REQUIRED_FIELDS.length);
+ simple.writeDelimitedTo(output);
+ System.out.println(Arrays.toString(output.toByteArray()));
+ System.out.println(Arrays.equals(WITH_REQUIRED_FIELDS, output.toByteArray()));
+ }
+}
diff --git a/src/test/examples/simpleproto1/keep-rules.txt b/src/test/examples/simpleproto1/keep-rules.txt
new file mode 100644
index 0000000..3c3c33f
--- /dev/null
+++ b/src/test/examples/simpleproto1/keep-rules.txt
@@ -0,0 +1,12 @@
+# Copyright (c) 2017, 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.
+
+# Keep the application entry point. Get rid of everything that is not
+# reachable from there.
+-keep public class simpleproto1.Simpleproto {
+ public static void main(...);
+}
+
+# allow access modification to enable minification
+-allowaccessmodification
diff --git a/src/test/examples/simpleproto1/simple.proto b/src/test/examples/simpleproto1/simple.proto
new file mode 100644
index 0000000..f4e1be4
--- /dev/null
+++ b/src/test/examples/simpleproto1/simple.proto
@@ -0,0 +1,14 @@
+// Copyright (c) 2016, 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.
+syntax = "proto2";
+package simpleproto1;
+
+option java_outer_classname = "GeneratedSimpleProto";
+
+message Simple {
+ required int32 id = 1;
+ required float unusedRequired = 2;
+ optional bool other = 3;
+}
+
diff --git a/src/test/examples/simpleproto2/Simpleproto.java b/src/test/examples/simpleproto2/Simpleproto.java
new file mode 100644
index 0000000..f333d72
--- /dev/null
+++ b/src/test/examples/simpleproto2/Simpleproto.java
@@ -0,0 +1,30 @@
+// Copyright (c) 2017, 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 simpleproto2;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import simpleproto2.GeneratedSimpleProto.Simple;
+
+/**
+ * A class that only uses a has method but otherwise ignores the value of a field.
+ */
+public class Simpleproto {
+
+ private static final byte[] WITHOUT_HASME_FIELD = new byte[]{2, 8, 42};
+ private static final byte[] WITH_HASME_FIELD = new byte[]{7, 8, 42, 21, 0, 0, -10, 66};
+
+ public static void main(String... args) throws IOException {
+ testHasWorks(WITHOUT_HASME_FIELD, false);
+ testHasWorks(WITH_HASME_FIELD, true);
+ }
+
+ private static void testHasWorks(byte[] msg, boolean expected) throws IOException {
+ ByteArrayInputStream input = new ByteArrayInputStream(msg);
+ Simple.Builder builder = Simple.newBuilder();
+ builder.mergeDelimitedFrom(input);
+ Simple simple = builder.build();
+ System.out.println("Expected " + expected + " and got " + simple.hasHasMe());
+ }
+}
diff --git a/src/test/examples/simpleproto2/keep-rules.txt b/src/test/examples/simpleproto2/keep-rules.txt
new file mode 100644
index 0000000..8f9c93e
--- /dev/null
+++ b/src/test/examples/simpleproto2/keep-rules.txt
@@ -0,0 +1,12 @@
+# Copyright (c) 2017, 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.
+
+# Keep the application entry point. Get rid of everything that is not
+# reachable from there.
+-keep public class simpleproto2.Simpleproto {
+ public static void main(...);
+}
+
+# allow access modification to enable minification
+-allowaccessmodification
diff --git a/src/test/examples/simpleproto2/simple.proto b/src/test/examples/simpleproto2/simple.proto
new file mode 100644
index 0000000..b9173e9
--- /dev/null
+++ b/src/test/examples/simpleproto2/simple.proto
@@ -0,0 +1,14 @@
+// Copyright (c) 2016, 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.
+syntax = "proto2";
+package simpleproto2;
+
+option java_outer_classname = "GeneratedSimpleProto";
+
+message Simple {
+ required int32 id = 1;
+ optional float hasMe = 2;
+ optional int32 other = 3;
+}
+
diff --git a/src/test/examples/simpleproto3/Simpleproto.java b/src/test/examples/simpleproto3/Simpleproto.java
new file mode 100644
index 0000000..2cdbae8
--- /dev/null
+++ b/src/test/examples/simpleproto3/Simpleproto.java
@@ -0,0 +1,65 @@
+// Copyright (c) 2017, 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 simpleproto3;
+
+import com.google.protobuf.UninitializedMessageException;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import simpleproto3.GeneratedSimpleProto.Simple;
+
+public class Simpleproto {
+
+ private static final byte[] WITH_REQUIRED_FIELDS = new byte[]{7, 8, 42, 21, 0, 0, -10, 66};
+ private static final byte[] WITH_MISSING_FIELD = new byte[]{2, 8, 42};
+
+
+ public static void main(String... args) throws IOException {
+ readProtoWithAllReqFields();
+ partialBuildFails();
+ partialReadFails();
+ }
+
+ private static void partialBuildFails() {
+ Simple.Builder builder = Simple.newBuilder();
+ builder.setId(32);
+ try {
+ builder.build();
+ } catch (UninitializedMessageException e) {
+ System.out.println("got exception");
+ }
+ }
+
+ private static void partialReadFails() throws IOException {
+ ByteArrayInputStream input = new ByteArrayInputStream(WITH_MISSING_FIELD);
+ Simple.Builder builder = Simple.newBuilder();
+ builder.mergeDelimitedFrom(input);
+ try {
+ builder.build();
+ } catch (UninitializedMessageException e) {
+ System.out.println("got exception");
+ }
+ }
+
+ private static void readProtoWithAllReqFields() throws IOException {
+ ByteArrayInputStream input = new ByteArrayInputStream(WITH_REQUIRED_FIELDS);
+ Simple.Builder builder = Simple.newBuilder();
+ builder.mergeDelimitedFrom(input);
+ Simple simple = builder.build();
+ ByteArrayOutputStream output = new ByteArrayOutputStream(WITH_REQUIRED_FIELDS.length);
+ simple.writeDelimitedTo(output);
+ System.out.println(isContained(WITH_REQUIRED_FIELDS, output.toByteArray()));
+ }
+
+ // After shaking, the serialized proto will no longer contain fields that are not referenced.
+ private static boolean isContained(byte[] fullBytes, byte[] reducedBytes) {
+ int j = 1;
+ for (int i = 1; i < fullBytes.length && j < reducedBytes.length; i++) {
+ if (fullBytes[i] == reducedBytes[j]) {
+ j++;
+ }
+ }
+ return j == reducedBytes.length;
+ }
+}
diff --git a/src/test/examples/simpleproto3/keep-rules.txt b/src/test/examples/simpleproto3/keep-rules.txt
new file mode 100644
index 0000000..186e9f8
--- /dev/null
+++ b/src/test/examples/simpleproto3/keep-rules.txt
@@ -0,0 +1,12 @@
+# Copyright (c) 2017, 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.
+
+# Keep the application entry point. Get rid of everything that is not
+# reachable from there.
+-keep public class simpleproto3.Simpleproto {
+ public static void main(...);
+}
+
+# allow access modification to enable minification
+-allowaccessmodification
diff --git a/src/test/examples/simpleproto3/simple.proto b/src/test/examples/simpleproto3/simple.proto
new file mode 100644
index 0000000..87512d1
--- /dev/null
+++ b/src/test/examples/simpleproto3/simple.proto
@@ -0,0 +1,14 @@
+// Copyright (c) 2016, 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.
+syntax = "proto3";
+package simpleproto3;
+
+option java_outer_classname = "GeneratedSimpleProto";
+
+message Simple {
+ int32 id = 1;
+ float unusedRequired = 2;
+ bool other = 3;
+}
+
diff --git a/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10DeployJarVerificationTest.java b/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10DeployJarVerificationTest.java
index afa437e..ca713fd 100644
--- a/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10DeployJarVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10DeployJarVerificationTest.java
@@ -9,27 +9,22 @@
import com.android.tools.r8.R8RunArtTestsTest.CompilerUnderTest;
import com.android.tools.r8.shaking.ProguardRuleParserException;
import com.android.tools.r8.utils.AndroidApp;
-import com.android.tools.r8.utils.InternalOptions;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import org.junit.Test;
public class R8GMSCoreV10DeployJarVerificationTest extends GMSCoreDeployJarVerificationTest {
- private void configureDeterministic(InternalOptions options) {
- options.removeSwitchMaps = false;
- }
-
@Test
public void buildFromDeployJar()
// TODO(tamaskenez): set hasReference = true when we have the noshrink file for V10
throws ExecutionException, IOException, ProguardRuleParserException, CompilationException {
AndroidApp app1 = buildFromDeployJar(
CompilerUnderTest.R8, CompilationMode.RELEASE,
- GMSCoreCompilationTestBase.GMSCORE_V10_DIR, false, this::configureDeterministic);
+ GMSCoreCompilationTestBase.GMSCORE_V10_DIR, false);
AndroidApp app2 = buildFromDeployJar(
CompilerUnderTest.R8, CompilationMode.RELEASE,
- GMSCoreCompilationTestBase.GMSCORE_V10_DIR, false, this::configureDeterministic);
+ GMSCoreCompilationTestBase.GMSCORE_V10_DIR, false);
// Verify that the result of the two compilations was the same.
assertIdenticalApplications(app1, app2);
diff --git a/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10TreeShakeJarVerificationTest.java b/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10TreeShakeJarVerificationTest.java
index 2640f13..766de9d 100644
--- a/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10TreeShakeJarVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10TreeShakeJarVerificationTest.java
@@ -20,7 +20,6 @@
private void configureDeterministic(InternalOptions options) {
options.skipMinification = true;
- options.removeSwitchMaps = false;
}
@Test
diff --git a/src/test/java/com/android/tools/r8/rewrite/switchmaps/RewriteSwitchMapsTest.java b/src/test/java/com/android/tools/r8/rewrite/switchmaps/RewriteSwitchMapsTest.java
index 646a481..4e8881a 100644
--- a/src/test/java/com/android/tools/r8/rewrite/switchmaps/RewriteSwitchMapsTest.java
+++ b/src/test/java/com/android/tools/r8/rewrite/switchmaps/RewriteSwitchMapsTest.java
@@ -13,7 +13,6 @@
import java.nio.file.Paths;
import java.util.concurrent.ExecutionException;
import org.junit.Assert;
-import org.junit.Ignore;
import org.junit.Test;
public class RewriteSwitchMapsTest extends TestBase {
@@ -24,8 +23,6 @@
"-keep class switchmaps.Switches { public static void main(...); } " +
"-dontobfuscate";
- // TODO(sgjesse): Re-enable this when the switch-map extraction has been fixed.
- @Ignore
@Test
public void checkSwitchMapsRemoved()
throws IOException, ProguardRuleParserException, ExecutionException, CompilationException {
diff --git a/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java b/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java
index 3435577..99be74a 100644
--- a/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java
@@ -372,6 +372,80 @@
subclass.method("double", "anotherMethod", ImmutableList.of("double")).isPresent());
}
+ private static void simpleproto1UnusedFieldIsGone(DexInspector inspector) {
+ ClassSubject protoClass = inspector.clazz("simpleproto1.GeneratedSimpleProto$Simple");
+ Assert.assertTrue(protoClass.isPresent());
+ Assert.assertFalse(protoClass.field("boolean", "other_").isPresent());
+ }
+
+ private static void simpleproto2UnusedFieldsAreGone(DexInspector inspector) {
+ ClassSubject protoClass = inspector.clazz("simpleproto2.GeneratedSimpleProto$Simple");
+ Assert.assertTrue(protoClass.isPresent());
+ Assert.assertFalse(protoClass.field("int", "id_").isPresent());
+ Assert.assertFalse(protoClass.field("float", "hasMe_").isPresent());
+ Assert.assertFalse(protoClass.field("int", "other_").isPresent());
+ }
+
+ private static void nestedproto1UnusedFieldsAreGone(DexInspector inspector) {
+ ClassSubject protoClass = inspector.clazz("nestedproto1.GeneratedNestedProto$Outer");
+ Assert.assertTrue(protoClass.isPresent());
+ Assert.assertFalse(protoClass.field("int", "id_").isPresent());
+ Assert.assertTrue(
+ protoClass.field("nestedproto1.GeneratedNestedProto$NestedOne", "inner_").isPresent());
+ Assert.assertFalse(
+ protoClass.field("nestedproto1.GeneratedNestedProto$NestedTwo", "inner2_").isPresent());
+ ClassSubject nestedOne = inspector.clazz("nestedproto1.GeneratedNestedProto$NestedOne");
+ Assert.assertTrue(nestedOne.isPresent());
+ Assert.assertTrue(nestedOne.field("java.lang.String", "other_").isPresent());
+ Assert.assertFalse(nestedOne.field("int", "id_").isPresent());
+ Assert.assertFalse(inspector.clazz("nestedproto1.GeneratedNestedProto$NestedTwo").isPresent());
+ }
+
+ private static void nestedproto2UnusedFieldsAreGone(DexInspector inspector) {
+ ClassSubject protoClass = inspector.clazz("nestedproto2.GeneratedNestedProto$Outer");
+ Assert.assertTrue(protoClass.isPresent());
+ Assert.assertTrue(protoClass.field("int", "id_").isPresent());
+ Assert.assertFalse(
+ protoClass.field("nestedproto2.GeneratedNestedProto$NestedOne", "inner_").isPresent());
+ Assert.assertFalse(
+ protoClass.field("nestedproto2.GeneratedNestedProto$NestedTwo", "inner2_").isPresent());
+ Assert.assertFalse(inspector.clazz("nestedproto2.GeneratedNestedProto$NestedOne").isPresent());
+ Assert.assertFalse(inspector.clazz("nestedproto2.GeneratedNestedProto$NestedTwo").isPresent());
+ }
+
+
+ private static void enumprotoUnusedFieldsAreGone(DexInspector inspector) {
+ ClassSubject protoClass = inspector.clazz("enumproto.GeneratedEnumProto$Enum");
+ Assert.assertTrue(protoClass.isPresent());
+ Assert.assertFalse(protoClass.field("int", "id_").isPresent());
+ Assert.assertTrue(protoClass.field("int", "enum_").isPresent());
+ Assert.assertFalse(protoClass.field("int", "other_").isPresent());
+ ClassSubject protoThreeClass = inspector.clazz("enumproto.three.GeneratedEnumProto$EnumThree");
+ Assert.assertTrue(protoThreeClass.isPresent());
+ Assert.assertFalse(protoThreeClass.field("int", "id_").isPresent());
+ Assert.assertTrue(protoThreeClass.field("int", "enum_").isPresent());
+ Assert.assertFalse(protoThreeClass.field("int", "other_").isPresent());
+ }
+
+ private static void repeatedUnusedFieldsAreGone(DexInspector inspector) {
+ ClassSubject protoClass = inspector.clazz("repeatedproto.GeneratedRepeatedProto$Repeated");
+ Assert.assertTrue(protoClass.isPresent());
+ Assert.assertFalse(protoClass.field("int", "id_").isPresent());
+ Assert.assertTrue(
+ protoClass.field("com.google.protobuf.Internal$ProtobufList", "repeated_").isPresent());
+ Assert.assertFalse(
+ protoClass.field("com.google.protobuf.Internal$ProtobufList", "sub_").isPresent());
+ Assert.assertFalse(
+ protoClass.field("com.google.protobuf.Internal$BooleanList", "other_").isPresent());
+ }
+
+ private static void oneofprotoUnusedFieldsAreGone(DexInspector inspector) {
+ ClassSubject protoClass = inspector.clazz("oneofproto.GeneratedOneOfProto$Oneof");
+ Assert.assertTrue(protoClass.isPresent());
+ Assert.assertFalse(protoClass.field("int", "id_").isPresent());
+ Assert.assertFalse(protoClass.field("Object", "otherfields_").isPresent());
+ }
+
private static List<String> names =
ImmutableList.of("pqr", "vw$", "abc", "def", "stu", "ghi", "jkl", "ea", "xyz_", "mno");
@@ -557,7 +631,15 @@
"assumevalues5",
"annotationremoval",
"memberrebinding2",
- "memberrebinding3");
+ "memberrebinding3",
+ "simpleproto1",
+ "simpleproto2",
+ "simpleproto3",
+ "nestedproto1",
+ "nestedproto2",
+ "enumproto",
+ "repeatedproto",
+ "oneofproto");
// Keys can be the name of the test or the name of the test followed by a colon and the name
// of the keep file.
@@ -614,6 +696,20 @@
inspections
.put("annotationremoval:keep-rules-keep-innerannotation.txt",
TreeShakingTest::annotationRemovalHasAllInnerClassAnnotations);
+ inspections
+ .put("simpleproto1:keep-rules.txt", TreeShakingTest::simpleproto1UnusedFieldIsGone);
+ inspections
+ .put("simpleproto2:keep-rules.txt", TreeShakingTest::simpleproto2UnusedFieldsAreGone);
+ inspections
+ .put("nestedproto1:keep-rules.txt", TreeShakingTest::nestedproto1UnusedFieldsAreGone);
+ inspections
+ .put("nestedproto2:keep-rules.txt", TreeShakingTest::nestedproto2UnusedFieldsAreGone);
+ inspections
+ .put("enumproto:keep-rules.txt", TreeShakingTest::enumprotoUnusedFieldsAreGone);
+ inspections
+ .put("repeatedproto:keep-rules.txt", TreeShakingTest::repeatedUnusedFieldsAreGone);
+ inspections
+ .put("oneofproto:keep-rules.txt", TreeShakingTest::oneofprotoUnusedFieldsAreGone);
// Keys can be the name of the test or the name of the test followed by a colon and the name
// of the keep file.
@@ -779,7 +875,7 @@
Collections.singletonList(generated.toString()), mainClass, extraArtArgs, null);
outputComparator.accept(output1, output2);
} else {
- ToolHelper.checkArtOutputIdentical(Collections.singletonList(originalDex),
+ String output = ToolHelper.checkArtOutputIdentical(Collections.singletonList(originalDex),
Collections.singletonList(generated.toString()), mainClass,
extraArtArgs, null);
}